Bug #81263 [Com]: Wrong result from DateTimeImmutable::diff

From: Date: Tue, 22 Mar 2022 21:52:49 +0000
Subject: Bug #81263 [Com]: Wrong result from DateTimeImmutable::diff
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-240457@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81263&edit=1

 ID:                 81263
 Comment by:         matthew at komputerwiz dot net
 Reported by:        mail at gh01 dot de
 Summary:            Wrong result from DateTimeImmutable::diff
 Status:             Assigned
 Type:               Bug
 Package:            Date/time related
 PHP Version:        master-Git-2021-07-15 (Git)
 Assigned To:        derick
 Block user comment: N
 Private report:     N

 New Comment:

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.


Previous Comments:
------------------------------------------------------------------------
[2021-10-21 13:23:19] cmb@php.net

This appears to be related to bug #81458.

------------------------------------------------------------------------
[2021-10-21 13:16:03] sjon@php.net

while the related https://3v4l.org/8g4NB seems fixed, this
issue remains

------------------------------------------------------------------------
[2021-10-07 22:36:34] mail at gh01 dot de

This issue still exists in current master: https://3v4l.org/f1fai/rfc#vgitmaster

------------------------------------------------------------------------
[2021-08-08 11:18:24] derick@php.net

Duplicate of #81273

------------------------------------------------------------------------
[2021-07-15 21:32:41] 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
)


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



--
Edit this bug report at https://bugs.php.net/bug.php?id=81263&edit=1


Thread (8 messages)

« previous php.bugs (#240457) next »