I discovered, in the course of working on my thread-safe time zone changes, an interesting side-effect of mktime(). The localsub() function sets tzname[tm->tm_isdst] to the correct zone abbreviation, as of the time it calculates. This is probably correct for localsub() as called by localtime(). However, since time2sub() calls localsub() (as the funcp passed it by mktime()), mktime() *also* sets tzname, to the time zone in effect at the time of mktime()'s argument. Additionally, because of time2sub()'s binary search, the other element of tzname (tzname[!tm->tm_isdst]) is often also set, to something random. (This will usually be the other time zone abbreviation in effect at that time, but it'd probably be pretty straightforward to construct some weird cases where it's a zone abbreviation used long in the past or future.) Is this: * a bug, which should be fixed in tzcode? * a feature, and thus I need to make sure this behavior is maintained by any changes I make to the guts of tzcode when adding the thread-safe functions? * undefined behavior, since mktime() behaves "as though it called tzset()", but tzset() is poorly defined in the presence of changing time zone abbreviations? The attached C program illustrates the behavior in question. (Europe/Riga uses EET/EEST now, but used MSK/MSD in 1981.) #include "tztimeext.h" #include <stdio.h> #include <stdlib.h> #include <string.h> struct tm then = { 0, /* int tm_sec; */ 0, /* int tm_min; */ 0, /* int tm_hour; */ 1, /* int tm_mday; */ 8, /* int tm_mon; */ 81, /* int tm_year; */ }; int main() { time_t now, then_t; struct tm* a_tm; putenv("TZ=Europe/Riga"); now = time(NULL); a_tm = localtime(&now); printf("now = %ld -- %s", (long) now, asctime(a_tm)); printf("tzname = {%s, %s}\n", tzname[0], tzname[1]); then_t = mktime(&then); printf("then = %ld -- %s", (long) then_t, asctime(&then)); printf("tzname = {%s, %s}\n", tzname[0], tzname[1]); exit(0); } -- Jonathan Lennox lennox@cs.columbia.edu