|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-07-15 21:32 UTC] mail at gh01 dot de
Description: ------------ PHP 8.0 (correct): https://3v4l.org/Wofuu#v8.0.8 PHP 8.1 (wrong): https://3v4l.org/Wofuu/rfc#vgit.master Test script: --------------- <?php $dt1 = new DateTimeImmutable('2020-07-19 18:30:00', new DateTimeZone('Europe/Berlin')); $dt2 = new DateTimeImmutable('2020-07-19 16:30:00', new DateTimeZone('UTC')); print_r($dt1->diff($dt2)); Expected result: ---------------- DateInterval Object ( [y] => 0 [m] => 0 [d] => 0 [h] => 0 [i] => 0 [s] => 0 [f] => 0 [weekday] => 0 [weekday_behavior] => 0 [first_last_day_of] => 0 [invert] => 0 [days] => 0 [special_type] => 0 [special_amount] => 0 [have_weekday_relative] => 0 [have_special_relative] => 0 ) Actual result: -------------- DateInterval Object ( [y] => -1 [m] => 11 [d] => 29 [h] => 24 [i] => 0 [s] => 0 [f] => 0 [weekday] => 0 [weekday_behavior] => 0 [first_last_day_of] => 0 [invert] => 0 [days] => 0 [special_type] => 0 [special_amount] => 0 [have_weekday_relative] => 0 [have_special_relative] => 0 ) PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 15:00:02 2025 UTC |
I pulled the latest source, compiled it, and ran the following example while in GDB: <?php $dFmt = \DateTimeInterface::ISO8601; $iFmt = '%R[%yy %mM %dd %hh %im %ss]'; // creates new DateTime for the current timezone (UTC-5 in my case) $exp = new \DateTime('+3600 seconds', new \DateTimeZone('-5')); echo 'expires: '.$exp->format($dFmt)."\n"; $gen = $exp->getTimestamp() - 3600; // creates new DateTime in UTC $genTime = \DateTime::createFromFormat('U', (string) $gen); echo 'created: '.$genTime->format($dFmt)."\n"; $ival = $exp->diff($genTime); echo 'interval: '.$ival->format($iFmt)."\n"; The expected interval output should be '-[0y 0M 0d 1h 0m 0s]', but is instead '-[-1y 11M 31d 1h 0m 0s]'. The problem seems to start around timelib.c:90, during the early relative normalization step. Just prior to this point, the `rt` struct contains: {y:0, m:0, d:0, h:-4, i:0, s:0, ...} The normalization step eliminates out-of-range negative values by "borrowing" from larger date units. After this point, `rt` contains: {y:-1, m:11, d:30, h:20, i:0, s:0, ...} When this is corrected for timezone offset (h += 5) and normalized again, it leads to the unexpected output above. Perhaps the issue stems from normalizing prior to correcting for time zone offset. If the timezone offset had been added prior to normalization, the "hours" field would have been in range.