[go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTime diff returns wrong sign on day count when using a timezone (Regression) #9880

Closed
neildaniels opened this issue Nov 2, 2022 · 5 comments

Comments

@neildaniels
Copy link

Description

The following code:

https://3v4l.org/7biFY

<?php

ini_set('date.timezone', 'America/Los_Angeles');

$nowTime = new DateTime();
$nowTime->setTimestamp(1667416695);

$dateTime = new DateTime();
$dateTime->setTimestamp(1671904800);
$dateTime->setTimezone(new DateTimeZone('America/New_York'));

echo $dateTime->diff($nowTime)->format('%r%a');

Resulted in this output:

51

But I expected this output instead:

-51

This code works as expected prior to 8.1.10.

If you comment out the $dateTime->setTimezone(new DateTimeZone('America/New_York')); line, the code works as expected on all versions.

PHP Version

PHP 8.1.12

Operating System

Alpine 3.16

@cmb69
Copy link
Member
cmb69 commented Nov 3, 2022

Indeed, this look completely wrong.

@cmb69
Copy link
Member
cmb69 commented Nov 3, 2022

This might be a duplicate of #9866.

@ayanozturk
Copy link

Similar difference in ->y value was introduced with PHP 8.1.10
https://3v4l.org/Wiane
It returns -1 instead of 0 when 2 dates with different timezones are compared.

@hormus
Copy link
hormus commented Nov 3, 2022
<?php
$utc = new DateTimeZone('UTC');
$london = new DateTimeZone('Europe/London');

$test1 = new \DateTime('2018-01-31', $utc);
$test2 = new \DateTime('2018-03-31 00:00:00', $london);

$dateDiff = $test2->diff($test1); // true absolute Should the interval be forced to be positive
//$dateDiff = $test1->diff($test2);
$bugs = array('y' => &$dateDiff->y, 'm' => &$dateDiff->m, 'd' => &$dateDiff->d, 'h' => &$dateDiff->h, 'invert' => &$dateDiff->invert, 'days' => &$dateDiff->days);
$test3 = new \DateTime('+2 month ' . $test1->format('Y-m-d\\TH:i:s\\Z'));

var_dump($test3->format('Y-m-d H:i:s +00:00'), $bugs);

?>

php >= 8.1.10

string(26) "2018-03-31 00:00:00 +00:00"
array(6) {
  ["y"]=>
  int(-1)
  ["m"]=>
  int(10)
  ["d"]=>
  int(0)
  ["h"]=>
  int(1)
  ["invert"]=>
  int(0)
  ["days"]=>
  int(58)
}

php all
If set $test2 = new \DateTime('2018-03-31 01:00:00', $london); and $test2->diff($test1) it's partial correct with inverter 1, if $test1->diff($test2) is correct

php < 8.1.10

string(26) "2018-03-31 00:00:00 +00:00"
array(6) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(1)
  ["d"]=>
  int(30)
  ["h"]=>
  int(23)
  ["invert"]=>
  int(1)
  ["days"]=>
  int(58)
}

if uncomment $dateDiff php < 8.1.10

string(26) "2018-03-31 00:00:00 +00:00"
array(6) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(1)
  ["d"]=>
  int(27)
  ["h"]=>
  int(23)
  ["invert"]=>
  int(0)
  ["days"]=>
  int(58)
}

@cmb69 it's great bug exists for function diff (don't only duplicate)

I am for restoring before creating same type timezone of php 8.1.10, adding a note in the manual for this use case otherwise the code needs improvement and I mean if different from same type it uses the same hacks that would be used with timezone type 3 Europe/Rome == Europe/Rome ... it is difficult to rewrite same type for this type of use.

derickr added a commit to derickr/php-src that referenced this issue Nov 30, 2022
@derickr
Copy link
Member
derickr commented Nov 30, 2022

Now fixed, for PHP 8.1.14 and PHP 8.2.1.

@derickr derickr closed this as completed Nov 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants
@derickr @neildaniels @ayanozturk @cmb69 @hormus and others