Take the 2-minute tour ×

I am executing below code.

int main()
struct tm storage={0,0,0,0,0,0,0,0,0};
char *p = NULL; 
p = (char *)strptime("2012-08-25 12:23:12","%Y-%m-%d %H:%M:%S",&storage);
char buff[1024]={0};
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage);
cout << buff << endl;
storage.tm_sec += 20;
cout << buff << endl;
cout << buff << endl;
return 0;

If above Program executed, It prints ' 2012-08-25 13:23:32' instead of '2012-08-25 12:23:32'. Please Help, why it is increasing tm_hour value. This works correctly if I put input date as '2012-02-25 12:23:32' in program, which is confusing.

OUtput ->

[user@rtpkvm55-vm2 root]$ ./a.out
2012-08-25 12:23:12
2012-08-25 12:23:32
2012-08-25 13:23:32
[user@rtpkvm55-vm2 root]$

Date Info on my system, -->

[user@rtpkvm55-vm2 root]$ date
Sat Aug 25 08:28:26 EDT 2012
share|improve this question
The code doesn't show that the hour is increasing. To do that, display the result that came from strptime as well as the result that came from the call to mktime. That will help pin down what's actually happening. –  Pete Becker Aug 25 '12 at 12:51
Sorry, I can't parse that. It has three outputs instead of one, but no indication of where they came from. Please update the sample code to match the output. –  Pete Becker Aug 25 '12 at 13:06

2 Answers 2

up vote 4 down vote accepted

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 of mktime
  • set the timezone to UTC before calling mktime (see also example from timegm) :
    setenv("TZ", "", 1);
  • 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)
share|improve this answer
Thanks, It Helped and explained me my doubt. Now I need to run my piece of code on both type of system(DST on & off). e.g. If I put tm_isdst = 1 in code before calling to mktime(), it will give incorrect result on system where DST is off(it will end up decreasing tm_hour by one). Is there any other way to add seconds to given date? (It May be "avoid using mktime()" or "Make smart use of mktime() which will ignore tm_isdst flag") –  Dhiraj Neve Aug 26 '12 at 2:38
@DhirajNeve: I added a couple of fixes. If you need to do more date/time related things, I think you should use a good C++ date/time library. –  rve Aug 26 '12 at 7:00

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.

share|improve this answer
According to man mktime (linux.die.net/man/3/mktime) it can (and does) alter stuct tm. It normalizes its values and fills in missing fields. –  rve Aug 25 '12 at 13:56
@rve it looks like you are right. I was misunderstood the wording. I thought it was normalizing for the purpose setting time_t. –  Jeffery Thomas Aug 26 '12 at 1:48
Yes, the implementation is wrong... –  ta.speot.is Aug 26 '12 at 1:56

Your Answer


