How to use mktime to respect time zones
How do I create a time-aware struct tm
in Linux/gcc?
I have the following code:
struct tm date;
date.tm_year=2012-1900;
date.tm_mon=9;
date.tm_mday=30;
date.tm_hour=17;
date.tm_min=45;
date.tm_sec=0;
date.tm_zone="America/New_York";
time_t t = mktime(&date);
When I print t
, the value is 1349045100
. So I think this is printed as a string using both C++ and Python and it returns me: Sun Sep 30 18:45:00 2012
It’s an hour break. I want 17:45 instead of 18:45. The python command I use is:
time.ctime(1349045100)
The C++ I use is:
::setenv("TZ", "America/New_York",1);
::tzset();
strftime(tm_str, len_tm_str, "%Y%m%d %H:%M:%S", ::localtime(&t));
So when I build the time, it seems to have rested for an hour. How can I correct this?
Solution
Your problem is almost certainly that the tm_isdst
flag of the tm
structure defaults to 0, which causes it to have no daylight saving time even in summer (your date is). Then, when you convert back to local time, it adds a DST offset, causing the difference you notice.
The simplest and often correct solution is to set the tm_isdst
member to -1 and let mktime
determine whether the date in question should have a DST offset applied.
Note that whether DST is in effect is orthogonal to the time zone you are using. Both need to be set up in the right way to display the results correctly.
If your application is likely to be threaded, also consider using localtime_r
instead of localtime
.