FW: America/Chicago zone vs mktime w/tm_isdst!=-1
Dan Nelson is not on the time zone mailing list; direct replies appropriately. --ado -----Original Message----- From: Dan Nelson [mailto:dnelson@allantgroup.com] Sent: Monday, November 24, 2003 6:23 PM To: tz@lecserver.nci.nih.gov Subject: America/Chicago zone vs mktime w/tm_isdst!=-1 Here's an interesting problem. Usually when mktime() is called with tm_isdst set to 0 or 1, it will interpret the original time as being either in standard or daylight time according to tm_isdst, and update the resulting time_t value (and the struct tm) if the DST flag was wrong. This doesn't seem to happen with the America/Chicago zone. I've attached a simple program that passes three struct tm's to mktime, with three values of tm_isdst each. For most zones, the first and last times change depending on what value of tm_isdst is passed in. For America/Chicago, it looks like tm_isdst is ignored. Is it used correctly for the middle time (since it's in the fall-back range). Someone filed a FreeBSD PR against this back in June ( http://www.freebsd.org/cgi/query-pr.cgi?pr=53899 ), and I've verified the behaviour back to FreeBSD 4.0 (which had imported tzcode1999a). The classictzcode.tar.gz on elsie.nci.nih.gov looks at tm_isdst in all cases, so the change happened sometime between 1994 and 1999. I don't know if there are archives of tzcode sources, or I could pinpoint the exact release. It's not strictly a bug since POSIX basically says that any tm_isdst != -1 results in implementation-defined behaviour, but it's troublesome if the behaviour changes from zone to zone, and the current releases of Solaris, Tru64, AIX, and glibc(Linux) are consistent across timezones (they all adjust the incoming struct tm based on tm_isdst). And, a couple of POSIX/C99 links for the archives: http://www.opengroup.org/onlinepubs/007904975/functions/mktime.html http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_280.htm -- Dan Nelson dnelson@allantgroup.com
Dan Nelson [mailto:dnelson@allantgroup.com] writes:
it's troublesome if the behaviour changes from zone to zone, and the current releases of Solaris, Tru64, AIX, and glibc(Linux) are consistent across timezones (they all adjust the incoming struct tm based on tm_isdst).
It seems clear to me that this is a bug in tzcode. The following patch fixes the problem on your test case, making tzcode act like Solaris and glibc except in the "could be either" case with isdst=-1 (which is clearly implementation-defined behavior). However, I should warn that I haven't a clue as to why this patch "works", and I suspect there are other examples where it won't work. I derived this patch merely by doing a diff between classic tzcode and current tzcode, and looking for "suspicious" changes. --- localtime.c 2003-09-16 04:12:40.000000000 -0700 +++ localtime1.c 2003-12-05 15:56:17.326492000 -0800 @@ -1536,10 +1536,10 @@ const long offset; if (sp == NULL) return WRONG; #endif /* defined ALL_STATE */ - for (samei = sp->typecnt - 1; samei >= 0; --samei) { + for (samei = 0; samei < sp->typecnt; samei++) { if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) continue; - for (otheri = sp->typecnt - 1; otheri >= 0; --otheri) { + for (otheri = 0; otheri < sp->typecnt; otheri++) { if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) continue; tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
participants (2)
-
Olson, Arthur David (NIH/NCI) -
Paul Eggert