mktime(): wrong value for DST taken?
Hi, Not sure whether it is related to mktime (see also http://mm.icann.org/pipermail/tz/2017-January/thread.html#24749), but I run into a similar issue. Consider the code below, and compile with (any) tz library (I tried with 2017A code). Save the source and compile with: gcc -o <out> <source> -L <tzdir> -ltz Running the produced exe results in: gcc -o ambigioustest2017a ambigioustest.c -L./tzcode2017a/ -ltz kdekker@nlbavlsm3.infor.com:/home/kdekker/downloads$ ./ambigioustest2017a enter mktime with: 1970/Jan/15278 00:119:30, week day: -858993460, year day: -858993460, dst: -1 the return value of mktime is: 1319957970 normalized times: 2011/Oct/30 01:59:30, week day: Sun, year day: 302, dst: 0 tz=EST, EDT Based on the provided TZ value, I expected that 01:59:30 is still in DST, and thus the returned value by mktime should be 1319954370 (i.e. one hour off). What I'm doing wrong, or what is wrong in the mktime() code? Please not that running the same source by using the built-in glibc mktime() function (i.e. gcc -o <exe> <sourcefile> and no additional flags), the result changes to: enter mktime with: 1970/Jan/15278 00:119:30, week day: -858993460, year day: -858993460, dst: -1 the return value of mktime is: 1319954370 normalized times: 2011/Oct/30 01:59:30, week day: Sun, year day: 302, dst: 1 tz=EST, EDT Note the minor differences with the previous output. Please let me know what should be correct? The provided source code is a part of our larger own test suite. Our test suite tests a wide range of values, especially near boundaries or ambiguous values. Regards, Kees /* start C-code */ #include <time.h> #include <stdio.h> int main(void) { int ret = 0; const char *months[] = { "Jan", "Feb", "Mar", "April", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec" }; const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Tur", "Fri", "Sat" }; // Back from daylight saving time to normal time. // In 2011, this happened October 30. // At 03:00 hours, local time was set back one hour. // So local time interval 02:00 - 03:00 hours is ambiguous: // It exists both in dayligth saving time and in normal time. putenv("TZ=EST5EDT,M4.1.0/02:00,M10.5.0/02:00"); struct tm tmp = { 30, 119, 0, 15278, 0, 70, -858993460, -858993460, -1}; printf("enter mktime with: %04d/%s/%02d %02d:%02d:%02d, week day: %d, year day: %d, dst: %d\n", tmp.tm_year + 1900, months[tmp.tm_mon], tmp.tm_mday, tmp.tm_hour, tmp.tm_min, tmp.tm_sec, tmp.tm_wday, tmp.tm_yday, tmp.tm_isdst); time_t t = mktime(&tmp); /* expect: t == 1319954370, DST is still on, because it still some seconds before 2:00 */ printf("the return value of mktime is: %lld\n", (long long)t); printf("normalized times: %04d/%s/%02d %02d:%02d:%02d, week day: %s, year day: %d, dst: %d\n", tmp.tm_year + 1900, months[tmp.tm_mon], tmp.tm_mday, tmp.tm_hour, tmp.tm_min, tmp.tm_sec, days[tmp.tm_wday], tmp.tm_yday, tmp.tm_isdst); if (t >= 0) { printf("tz=%s, %s\n", tzname[0], tzname[1]); } return 0; } /* End-of-C-Code */
Kees Dekker wrote:
Based on the provided TZ value, I expected that 01:59:30 is still in DST, and thus the returned value by mktime should be 1319954370 (i.e. one hour off).
You have misunderstood the timing of the DST transition. The time of day given in the TZ variable is interpreted according to local time as it was prior to the transition. So your "/02:00" means that, at the end of DST, local time jumps back from 02:00 to 01:00. (Jumping at this time of day is in fact US practice.) Local times from 01:00 (inclusive) to 02:00 (exclusive) are ambiguous. Your input falls within the ambiguous period, so mktime() would be entitled to return either 1319954370 with isdst=1 (as you expected and as glibc did) or 1319957970 with isdst=0 (as the tz library did). -zefram
participants (2)
-
Kees Dekker -
Zefram