Fix for php4 bug #30096

php.internals

Vladimir Zidar

21 years ago
If anybody cares, gmmktime returning completly bogus results. It can be easly checked out by manually setting TZ shell variable. Lets try it like this: TZ=GMT+1 php -r "echo gmmktime();" gives 1100292805 TZ=GMT+2 php -r "echo gmmktime();" gives 1100289207 TZ=GMT+3 php -r "echo gmmktime();" gives 1100285610 But it should return always the same time (ok, few seconds here and there, needed to type each command..) no matter which timezone is set. Why ? Because 'tm_gmtoff' (and gmadjust manually calculated from 'timezone' and 'is_dst' in cases where tm_gmtoff is not available) shows number of seconds EAST from GMT (man localtime is your friend here). So to get GMT time from, we have to _substract_ this number from localtime, and what is php currently doing, is adding it to localtime, which can't be a good thing no matter how you look at it (-: So the fix is easy: --- ext/standard/datetime.c.orig Fri Nov 12 22:35:04 2004 +++ ext/standard/datetime.c Fri Nov 12 22:35:33 2004 @@ -256,7 +256,7 @@ gmadjust = -(is_dst ? timezone - 3600 : timezone); #endif #endif - seconds += gmadjust; + seconds -= gmadjust; } RETURN_LONG(seconds);

Derick Rethans

21 years ago
On Mon, 15 Nov 2004, Vladimir Zidar wrote:
> If anybody cares, > > gmmktime returning completly bogus results. It can be easly checked out > by manually setting TZ shell variable.
I can reproduce it, and I'll investigate whether this is not going to break other things. Derick
-- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org

Vladimir Zidar

21 years ago
Yes, please do so. I just found the fix by carefully reading man pages for localtime and tzset. On Mon, 2004-11-15 at 16:12, Derick Rethans wrote:
> On Mon, 15 Nov 2004, Vladimir Zidar wrote: > > > If anybody cares, > > > > gmmktime returning completly bogus results. It can be easly checked out > > by manually setting TZ shell variable. > > I can reproduce it, and I'll investigate whether this is not going to > break other things. > > Derick
-- Vladimir Zidar, Programmer MindNever Foodstuff TRDG. Head Office Branch Tel: +381-63-550161, +385-98-9574261 http://www.mindnever.org, icq: 15414204, mail: mr_W@mindnever.org

Antony Dovgal

21 years ago
On Mon, 15 Nov 2004 16:04:46 +0100 Vladimir Zidar <vladimir@mindnever.org> wrote:
> If anybody cares, > > gmmktime returning completly bogus results. It can be easly checked > out by manually setting TZ shell variable. > > Lets try it like this: > > TZ=GMT+1 php -r "echo gmmktime();" > > gives 1100292805 > > TZ=GMT+2 php -r "echo gmmktime();" > > gives 1100289207 > > TZ=GMT+3 php -r "echo gmmktime();" > > gives 1100285610 > > But it should return always the same time (ok, few seconds here and > there, needed to type each command..) no matter which timezone is set. >
I wonder why it wasn't noticed before, cause CVS says it was introduced ages ago: http://cvs.php.net/co.php/php-src/ext/standard/datetime.c?r=1.8 http://cvs.php.net/diff.php/php-src/ext/standard/datetime.c?r1=1.7&r2=1.8&ty=u
-- Wbr, Antony Dovgal aka tony2001 tony2001@phpclub.net || antony@dovgal.com

Derick Rethans

21 years ago
On Mon, 15 Nov 2004, Vladimir Zidar wrote:
> So the fix is easy: > > --- ext/standard/datetime.c.orig Fri Nov 12 22:35:04 2004 > +++ ext/standard/datetime.c Fri Nov 12 22:35:33 2004 > @@ -256,7 +256,7 @@ > gmadjust = -(is_dst ? timezone - 3600 : timezone); > #endif > #endif > - seconds += gmadjust; > + seconds -= gmadjust; > } > > RETURN_LONG(seconds);
This fix is wrong, the example now returns definitely the wrong answer: derick@kossu:/dat/dev/php/php-5.0dev$ cat ext/standard/tests/time/bug30096.php <?php echo gmdate("H:i:s Y-m-d", gmmktime(02,00,01, 03,28,2004)); ?> derick@kossu:/dat/dev/php/php-5.0dev$ sapi/cli/php ext/standard/tests/time/bug30096.php 23:00:01 2004-03-27 This bug has nothing to do with the wrong direction of the adjustment, but more with the chancing to DST at that date. regards, Derick
-- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org

Vladimir Zidar

21 years ago
But then whole function php_mktime() is wrong, as in case where gm=1, you expect that parameters you pass are GMT, and still you fill defaults with localtime. Also, later, if gm=1, timezone adjustment is in use, but with parameters that are in GMT. So the real good fix would be to remove timezone stuff completly out of there, and make another function in pair with php_localtime_r, that returns GMT, and to use it when gm=1. On Mon, 2004-11-15 at 17:54, Derick Rethans wrote:
> On Mon, 15 Nov 2004, Vladimir Zidar wrote: > > > So the fix is easy: > > > > --- ext/standard/datetime.c.orig Fri Nov 12 22:35:04 2004 > > +++ ext/standard/datetime.c Fri Nov 12 22:35:33 2004 > > @@ -256,7 +256,7 @@ > > gmadjust = -(is_dst ? timezone - 3600 : timezone); > > #endif > > #endif > > - seconds += gmadjust; > > + seconds -= gmadjust; > > } > > > > RETURN_LONG(seconds); > > This fix is wrong, the example now returns definitely the wrong answer: > > derick@kossu:/dat/dev/php/php-5.0dev$ cat ext/standard/tests/time/bug30096.php > <?php > echo gmdate("H:i:s Y-m-d", gmmktime(02,00,01, 03,28,2004)); > ?> > > derick@kossu:/dat/dev/php/php-5.0dev$ sapi/cli/php ext/standard/tests/time/bug30096.php > 23:00:01 2004-03-27 > > This bug has nothing to do with the wrong direction of the adjustment, > but more with the chancing to DST at that date. > > regards, > Derick
-- Vladimir Zidar, Programmer MindNever Foodstuff TRDG. Head Office Branch Tel: +381-63-550161, +385-98-9574261 http://www.mindnever.org, icq: 15414204, mail: mr_W@mindnever.org

Derick Rethans

21 years ago
On Mon, 15 Nov 2004, Vladimir Zidar wrote:
> But then whole function php_mktime() is wrong, as in case where gm=1, > you expect that parameters you pass are GMT, and still you fill defaults > with localtime. Also, later, if gm=1, timezone adjustment is in use, but > with parameters that are in GMT. > > So the real good fix would be to remove timezone stuff completly out of > there, and make another function in pair with php_localtime_r, that > returns GMT, and to use it when gm=1.
Sure, that's why I'm rewriting this stuff for PHP 5 ;-) regards, Derick
-- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org

Vladimir Zidar

21 years ago
On Mon, 2004-11-15 at 18:37, Derick Rethans wrote:
> On Mon, 15 Nov 2004, Vladimir Zidar wrote: > > > But then whole function php_mktime() is wrong, as in case where gm=1, > > you expect that parameters you pass are GMT, and still you fill defaults > > with localtime. Also, later, if gm=1, timezone adjustment is in use, but > > with parameters that are in GMT. > > > > So the real good fix would be to remove timezone stuff completly out of > > there, and make another function in pair with php_localtime_r, that > > returns GMT, and to use it when gm=1. > > Sure, that's why I'm rewriting this stuff for PHP 5 ;-)
I can see now that there is php_gmtime_r() function also. Can we use this when gm=1, and forget about timezone there ? I'll check now.