IMPORTANT: Timezone patch

From: Date: Tue, 13 Jun 2000 20:08:58 +0000
Subject: IMPORTANT: Timezone patch
Groups: php.dev php.general 
Request: Send a blank email to php-dev+get-21244@lists.php.net to get a copy of this message
Basically, I noticed the error when I wanted to take a GMT date/time and convert it to local time. Before the patch the output of the code below was totally wrong - it did not account for non-HAVE_TM_GMTOFF case where timezone offsets are positive instead of negative, like in HAVE_TM_GMTOFF case. Solaris was one of the systems affected, for example. Furthermore, it didn't seem to do daylight savings time adjustment correctly. Without the patch the following code (for CDT timezone = -0500): <? var_dump(date("M d, Y H:i:s", gmmktime(12, 0, 0, 6, 9, 2000))); var_dump(date("M d, Y H:i:s", gmmktime(12, 0, 0, 6, 9, 2000, 1))); var_dump(date("M d, Y H:i:s", gmmktime(12, 0, 0, 6, 9, 2000, 0))); ?> gave: string(21) "Jun 09, 2000 18:00:00" string(21) "Jun 09, 2000 18:00:00" string(21) "Jun 09, 2000 19:00:00" with the patch it gives: string(21) "Jun 09, 2000 07:00:00" string(21) "Jun 09, 2000 07:00:00" string(21) "Jun 09, 2000 06:00:00" Which is exactly what I'd expect for noon GMT time for my timezone. So, I propose the attached patch. Please test it and comment so that we know whether to put it in 4.0.1. -Andrei When we eliminate the impossible, whatever remains, however improbable, must be true. -- Sherlock Holmes

Index: ext/standard/datetime.c =================================================================== RCS file: /repository/php4/ext/standard/datetime.c,v retrieving revision 1.43 diff -u -r1.43 datetime.c --- ext/standard/datetime.c 2000/06/09 20:18:36 1.43 +++ ext/standard/datetime.c 2000/06/12 20:08:14 @@ -53,7 +53,7 @@ }; #if !defined(HAVE_TM_ZONE) && !defined(_TIMEZONE) && !defined(HAVE_DECLARED_TIMEZONE) -extern time_t timezone; +extern time_t timezone, altzone; extern int daylight; #endif @@ -81,6 +81,7 @@ struct tm *ta, tmbuf; time_t t; int i, gmadjust, seconds, arg_count = ZEND_NUM_ARGS(); + int is_dst = -1; if (arg_count > 7 || zend_get_parameters_array_ex(arg_count,arguments) == FAILURE) { WRONG_PARAM_COUNT; @@ -116,7 +117,7 @@ */ switch(arg_count) { case 7: - ta->tm_isdst = (*arguments[6])->value.lval; + ta->tm_isdst = is_dst = (*arguments[6])->value.lval; /* fall-through */ case 6: /* @@ -155,6 +156,8 @@ } seconds = mktime(ta); + if (is_dst == -1) + is_dst = ta->tm_isdst; if (gm) { #if HAVE_TM_GMTOFF @@ -165,11 +168,12 @@ gmadjust = ta->tm_gmtoff; #else /* - ** Without tm_gmtoff, the non-ANSI C run-time global 'timezone' - ** variable simply returns the current Winter GMT offset - ** in the current locale (defined in DOS/Windows compilers). + ** If correcting for daylight savings time, we set the adjustment to + ** the value of altzone variable. Otherwise, we need to overcorrect and + ** set the adjustment to the main timezone offset plus difference + ** between the main and alternate ones. */ - gmadjust = timezone; + gmadjust = -(is_dst ? altzone : timezone + (timezone - altzone)); #endif seconds += gmadjust; } @@ -405,9 +409,9 @@ break; case 'Z': /* timezone offset in seconds */ #if HAVE_TM_GMTOFF - sprintf(tmp_buff, "%ld", ta->tm_isdst ? ta->tm_gmtoff-3600 : ta->tm_gmtoff); + sprintf(tmp_buff, "%ld", ta->tm_gmtoff); #else - sprintf(tmp_buff, "%ld", daylight ? timezone-3600 : timezone); + sprintf(tmp_buff, "%ld", ta->tm_isdst ? altzone : timezone); #endif strcat(return_value->value.str.val, tmp_buff); break; @@ -720,8 +724,8 @@ RETURN_LONG(parsedate((*timep)->value.str.val, NULL)); } } - /* }}} */ + /* * Local variables:
« previous php.dev (#21244) next »