Subject: 1.12.m1 beta3 timezone bugs (was: Wrong DST in timezone MET) To: louram AT xs4all DOT nl (Lou Ramaekers) Date: Tue, 30 Aug 1994 10:42:20 +0200 (MET DST) From: Henrik Storner Cc: dj AT ctron DOT com, djgpp AT sun DOT soe DOT clarkson DOT edu The beta3 version of dj112m1 have several bugs in the timezone handling code, arising from the use of the _timezone and _daylight variables declared in ctime.c . First of all, as I posted yesterday, these should be declared as 'long' instead of 'time_t' (which is an unsigned long), as they may very well contain negative values. This is the cause of the mysterious timezone offsets reported by ftime() when using timezones with negative GMT offsets. However, these variables are also used by gettimeofday() and stat_assist() which is just plain wrong! They are used as if they contain the _current_ gmt-offset and DST flag, but they don't: Look at tzsetname() in ctime.c and you'll see that they contain the last rule defined for the current timezone. This usually is the rule when DST is in effect; thus by pure accident we get correct behaviour right now, but not when DST ends. The gettimeofday() and stat_assist() should use mktime() to determine the gmt-offset and dst-flag settings, which is easily done as mktime() is already used by those routines. I belive the _timezone and _daylight variables should be declared 'static' to avoid using them by accident. Diffs to the library routines follows. *** libsrc/c/gen/ctime.old Sun Aug 28 02:08:52 1994 --- libsrc/c/gen/ctime.c Tue Aug 30 14:38:44 1994 *************** *** 199,205 **** }; ! time_t _timezone = 0; ! int _daylight = 0; ! time_t _altzone = 0; static long --- 199,205 ---- }; ! static long _timezone = 0; ! static int _daylight = 0; ! static long _altzone = 0; static long *** libsrc/c/sys/gettimeo.old Sun Aug 28 02:01:50 1994 --- libsrc/c/sys/gettimeo.c Tue Aug 30 14:26:50 1994 *************** *** 18,24 **** #include - extern time_t _timezone; - extern time_t _altzone; - extern int _daylight; extern void _tzset_maybe(void); --- 18,21 ---- *************** *** 51,55 **** tmblk.tm_wday = tmblk.tm_yday = tmblk.tm_isdst = tmblk.tm_gmtoff = 0; tmblk.tm_zone = NULL; ! tmblk.tm_isdst = _daylight; tv->tv_sec = mktime(&tmblk); --- 48,52 ---- tmblk.tm_wday = tmblk.tm_yday = tmblk.tm_isdst = tmblk.tm_gmtoff = 0; tmblk.tm_zone = NULL; ! tmblk.tm_isdst = -1; tv->tv_sec = mktime(&tmblk); *************** *** 57,62 **** if(tz) { ! tz->tz_minuteswest = _timezone/60; ! tz->tz_dsttime = _daylight; } return 0; --- 54,61 ---- if(tz) { ! tz->tz_minuteswest = -tmblk.tm_gmtoff/60; ! tz->tz_dsttime = tmblk.tm_isdst; ! if (tmblk.tm_isdst) ! tz->tz_minuteswest += 60; } return 0; *** libsrc/c/sys/stat_ast.old Sun Aug 28 01:56:40 1994 --- libsrc/c/sys/stat_ast.c Tue Aug 30 14:26:50 1994 *************** *** 25,30 **** extern void _tzset_maybe(void); - extern int _daylight; - int stat_assist(const char* filename, struct stat* statbf) { --- 25,28 ---- *************** *** 105,109 **** tmblk.tm_wday = tmblk.tm_yday = tmblk.tm_isdst = tmblk.tm_gmtoff = 0; tmblk.tm_zone = NULL; ! tmblk.tm_isdst = _daylight; statbf->st_ctime = mktime(&tmblk); --- 103,107 ---- tmblk.tm_wday = tmblk.tm_yday = tmblk.tm_isdst = tmblk.tm_gmtoff = 0; tmblk.tm_zone = NULL; ! tmblk.tm_isdst = -1; statbf->st_ctime = mktime(&tmblk); -- Henrik Storner | "Man is the best computer we can put aboard a space- (storner AT olicom DOT dk) | craft ... and the only one that can be mass produced System Engineering | with unskilled labor." Olicom Denmark | Wernher von Braun