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

From: Date: Mon, 11 Oct 2021 07:57:26 +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-237130@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:         alec at alec dot pl
 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:

This is a bug and a regression. I hope it gets more attention before the final release.

From a user perspective it is obvious that the compared DateTime objects needs to be "converted
internally" to the same timezone to do the calculations.


Previous Comments:
------------------------------------------------------------------------
[2021-09-19 22:20:39] antonino dot spampinato86 at gmail dot com

sorry for my english, if you use DateTime :: diff the value is a number sequence. From php 8 it
incorrectly calculates the moment, i.e. the date string is the first parameter of DateTime between
two dates, the result is 20 instead of 24 hours (one day). It is a bug but also php <8 which
converts the date string to UTC, ie it loses or adds hours that expand per day. php <8 previously
2018-07-01 20:00:00 America / Toronto in diff was converted to 2018-07-02 00:00:00 UTC instead of
using moment. Wait to hear from maintainer @dereck. i am a simple user i don't work for php :)

<?php

$first = (new DateTime('2018-07-01 00:00:00.000000 America/Toronto'))
    ->setTimezone(new DateTimeZone('UTC')); // 2018-07-01 04:00:00 UTC
$second = new DateTime('2018-07-02 00:00:00.000000 America/Toronto');

var_dump($first->diff($second)->days); //2018-07-01 04:00:00 UTC - 2018-07-02 00:00
Anerica/Toronto = 20 hours
var_dump($first->diff($second)->d);
var_dump($first->diff($second)->h);

------------------------------------------------------------------------
[2021-09-19 19:33:04] kylekatarnls at gmail dot com

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.

------------------------------------------------------------------------
[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.

------------------------------------------------------------------------


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


Thread (22 messages)

« previous php.bugs (#237130) next »