Bug #81458 [Asn]: Regression in PHP 8.1: Incorrect difference after timezone change

From: Date: Fri, 05 Nov 2021 12:46:17 +0000
Subject: Bug #81458 [Asn]: Regression in PHP 8.1: Incorrect difference after timezone change
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-237567@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81458&edit=1 ID: 81458 Updated by: derick@php.net Reported by: kylekatarnls at gmail dot com Summary: Regression in PHP 8.1: Incorrect difference after timezone change Status: Assigned Type: Bug Package: Date/time related PHP Version: 8.1Git-2021-09-18 (Git) Assigned To: derick Block user comment: N Private report: N New Comment: FWIW, I started working on this, but it's a tad more work than I expected. Previous Comments: ------------------------------------------------------------------------ [2021-11-02 21:00:33] kylekatarnls at gmail dot com Exactly absolute(floor(($one->unixTime - $two->unixTime) / 86400)) is a good fallback to calendar diff when ambiguous. Thank you. ------------------------------------------------------------------------ [2021-11-02 15:31:59] derick@php.net Kyle, would you agree to the following definition of what "days" should mean in this context? It was never really defined (https://www.php.net/manual/en/class.dateinterval.php#dateinterval.props.days) in the docs: - If the timezones are the same¹, use the values of year, month, and day to calculate "days" - If the timezones are not the same, use absolute(floor(($one->unixTime - $two->unixTime) / 86400)) ¹ A timezone is the same if both $one and $two are: - the same timezone type (1, 2, or 3) AND - if zonetype 1 (utc offset) or 2 (abbr), the UTC offsets are the same - if zonetype 3, the TZIDs (such as UTC / America/Toronto) are the same In your example, the timezone in $first and $second is not the same, as $first is zonetype 3 and has TZID "UTC", and $second is zonetype 3, but has the TZID "America/Toronto". If would then calculate absolute(floor((1530504000 - 1530417600) / 86400)) === 1. ------------------------------------------------------------------------ [2021-10-21 16:58:52] kylekatarnls at gmail dot com cmb@php.net > No, the difference between those 2 moments is 24 hours, not 20 hours. No hours are added or subtracted when calling setTimezone, only the timezone change not the moment, it's a meta data that should be used only to format the date, it has no impact on the difference with an other moment. Sorry but no, the current behavior is not correct. No way, 1 is correct (it's really 1 FULL DAY diff), and 0 is wrong. ------------------------------------------------------------------------ [2021-10-21 15:42:59] antonino dot spampinato86 at gmail dot com days If the DateInterval object was created by DateTime::diff(), then this is the total number of days between the start and end dates. Otherwise, days will be false. Before PHP 5.4.20/5.5.4 instead of FALSE you will receive -99999 upon accessing the property. It is a bug, however a date can be less than a day this can be handled by the user code side. ------------------------------------------------------------------------ [2021-10-21 15:13:07] antonino dot spampinato86 at gmail dot com After explaining the difference between the new diff behavior from php 8.1 the algorithm has also changed unfortunately SetTimeZone uses the server time and not the DateTime diff object does not recognize +00: 00 but UTC for this reason forces UTC in the code. $first = (new DateTime('2018-07-01 00:00:00.000000 America/Toronto')); $first = (new DateTime('@' . $first->format('U'))); $first = (new DateTime($first->format('Y-m-d H:i:s'), new DateTimeZone('UTC'))); // ->setTimezone(new DateTimeZone('UTC')); $second = new DateTime('2018-07-02 00:00:00.000000 America/Toronto'); $result = $first->diff($second); var_dump($first); var_dump($second); var_dump('UTC ' . ((new DateTime('@' . $second->format('U')))->format('Y-m-d H:i:s'))); var_dump($result->days); var_dump($result->d); var_dump($result); ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=81458 -- Edit this bug report at https://bugs.php.net/bug.php?id=81458&edit=1

« previous php.bugs (#237567) next »