Confusing behaviour of mktime() function : increasing tm_hour count by one
Wow, there just is no way around it. It must be a bug in your system's implementation of mktime(3). mktime(3) should not alter the struct tm *
passed to it.
I would suggest checking the value of storage.tm_isdst
. Try setting it to 0 to ensure it's not confused about DST. If that doesn't work, try setting it to -1 to let it auto determine the proper value.
mktime - convert broken-down time into time since the Epoch
A positive or 0 value for tm_isdst causes mktime() to presume initially that Daylight Savings Time, respectively, is or is not in effect for the specified time. A negative value for tm_isdst causes mktime() to attempt to determine whether Daylight Saving Time is in effect for the specified time.
I was wrong about mktime(3) not modifying struct tm *
. It is the correct behavior to normalize the value.
What happens
The date you specified has daylight savings in effect but when calling mktime
, storage.tm_isdst
is zero. mktime
sees this and thinks "hey, they gave me a date with an incorrect daylight savings flag, lets fix it". Then it sets tm_isdst
to 1 and changes tm_hour
.
See also this answer.
To fix it
- use
timegm
instead ofmktime
- set the timezone to UTC before calling
mktime
(see also example fromtimegm
) :setenv("TZ", "", 1); tzset(); mktime();
- use a good date-time library (like boost::locale::date_time/boost::date_time, but read the Q&A section on the
boost::locale::date_time
page before picking one)