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

From: Date: Sun, 19 Sep 2021 19:33:04 +0000
Subject: Bug #81458 [Com]: Regression in PHP 8.1: Incorrect difference after timezone change
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-236704@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 Comment by: kylekatarnls at gmail dot com Reported by: kylekatarnls at gmail dot com Summary: Regression in PHP 8.1: Incorrect difference after timezone change Status: Open Type: Bug Package: Date/time related PHP Version: 8.1Git-2021-09-18 (Git) Block user comment: N Private report: N New Comment: Again, I may understand the point about 1 being not the correct result, and that false would be the correct one. But why 0? It's non sense. I know it's very tempting when facing a regression to blame users expectations or previous versions to be wrong. That looks to me like a confirmation bias. Please triple-check this int(0) value in an objective way. How can it be correct? If you "can't" calculate, then return false please, so we can detect it when checking an interval. Thanks. Previous Comments: ------------------------------------------------------------------------ [2021-09-19 15:15:53] antonino dot spampinato86 at gmail dot com Carbon or php <8.1 does not use the right code, a date must be calculated from its own moment. This speech is true only if between the same, otherwise offset first normalizes the date and then you convert to UTC or look at how many DST or ST between two dates with different offset and currently the php code does not provide this. It's arithmetic. Perhaps it would make sense to change into fatal error if calculating two dates with different time zones. Human 2018-07-01 04:00:00 UTC to 2018-07-02 00:00:00 America/Toronto bug moment is 20 hours for diff, if converter to 2018-07-02 04:00:00 is 24 hours (maybe one day if without transitions DST or ST). ------------------------------------------------------------------------ [2021-09-19 14:55:54] kylekatarnls at gmail dot com So we should get false, not 0, we still have a bug then. Moreover, we still have an integer number of days for the diff(), the timezone difference should have no impact there, as in real life you can have UTC vs. User timezone in similar comparisons, and then you will get different output depending on user timezone, and it will change from PHP 8.0 to 8.1, that's very dangerous. For the library I maintain, then I have no choice but to convert date timezone for each date only for PHP 8.1 (as behavior is safe < 8.1), that will make the library (nesbot/carbon) slower in PHP 8.1, that's a bit sad I think. And this is a breaking change, that should be carefully documented if you don't fix it. ------------------------------------------------------------------------ [2021-09-19 14:43:15] antonino dot spampinato86 at gmail dot com Sorry correct: 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. d Number of days. ------------------------------------------------------------------------ [2021-09-19 14:39:54] antonino dot spampinato86 at gmail dot com Since php 8.1 diff uses the moment instead of the timestamp, D indicates the days not covered by the month while days the days. then day one with zero time and with positive offset in timestamp (UTC) becomes the last of the previous month. For maximum compatibility check between dates that have the same timezone otherwise apply your diff method. Related bug #52480 ------------------------------------------------------------------------ [2021-09-18 19:56:21] kylekatarnls at gmail dot com Description: ------------ In PHP 8.0 diff()->days returned the total number of days between dates even if one of them were in UTC and not the other In PHP 8.1 (since beta3 I think) ->d is still OK but ->days is now 0 Test script: --------------- <?php $first = (new DateTime('2018-07-01 00:00:00.000000 America/Toronto')) ->setTimezone(new DateTimeZone('UTC')); $second = new DateTime('2018-07-02 00:00:00.000000 America/Toronto'); var_dump($first->diff($second)->days); var_dump($first->diff($second)->d); Expected result: ---------------- int(1) int(1) Actual result: -------------- int(0) int(1) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=81458&edit=1

« previous php.bugs (#236704) next »