Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing behaviour of mktime on Linux?

I am using the mktime(struct tm*) function in Suse 10.

Now, I am noticing some strange behaviour when daylight saving time is enabled. Let's say I have enabled daylight saving time to begin on Sep 15 at 18:10 and the daylight correction is for 30 minutes. Now, when I call mktime with tm structure having the date as Sep 15 18:10 and tm_isdst is set to 0, then I get back the same values in the tm structure only with the tm_isdst set to 1.

But, if the pass the date as Sep 15 18:10 with tm_isdst set to 1, then I find the time changed to 17:40. This correction in the tm structure is noticed for time passed between Sep 15 18:10 to Sep 15 18:40, but after that no correction in time happens and teh dst flag remains enabled. Even if I pass the date as Sep 16 18:10, no time correction happens only dst flag remains enabled.

I am totally confused. Is this the correct behavior of mktime?

like image 700
Jay Avatar asked Sep 16 '11 14:09

Jay


1 Answers

If the local time changes by 30 minutes for DST, then once per year there's 30 minutes of local time that happens twice (once with DST, and once without) and another 30 minutes that never happens (it gets skipped when the time changes).

So local times within 30 minutes of when the clock gets set back are ambiguous, unless whether DST is in effect is specified; there are two actual instants in time that they could correspond to.

Local times within 30 minutes of when the clock gets set ahead are invalid; there are no actual instants in time they could correspond to (though the conversion might still be done by supposing that DST is in effect, or not in effect).

So for some local times (ignoring the DST state) there could be more than one corresponding UTC time, but for any given UTC time there is only one possible local time (if DST adjustments are accounted for properly).

When you call mktime, it's converting the local time you give it to a time_t as though DST is either in effect or not, depending on the value of tm_isdst. The corrected values you get back are based on the reverse of this conversion, and the system will determine whether you get a DST time or a non-DST time, depending on its idea of whether DST is in effect at the time from the conversion. The time you gave it and the time you got back actually represent the same moment in time, but with different offsets from UTC due to the different DST states.

So yes, this is the correct behaviour of mktime. It is supposed to normalize the values in the structure, according to its idea of how to properly represent the time you gave it.

This also illustrates why one should be careful about using local time keep track of actual events -- if the DST state or offset from UTC is not saved along with the time, some local time values can be ambiguous.

like image 134
Dmitri Avatar answered Sep 27 '22 19:09

Dmitri