[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

Time zone bug with \DateTimeInterface::diff() #9866

Closed
jack-worman opened this issue Nov 1, 2022 · 3 comments
Closed

Time zone bug with \DateTimeInterface::diff() #9866

jack-worman opened this issue Nov 1, 2022 · 3 comments

Comments

@jack-worman
Copy link
jack-worman commented Nov 1, 2022

Description

The following code:

<?php

function getYearsBetween(
    \DateTimeImmutable $startDate,
    \DateTimeImmutable $endDate,
): int {
    $dateInterval = $startDate->diff($endDate, true);
    return $dateInterval->y;
}

$start = new \DateTimeImmutable('2000-11-01 09:29:22.907606', new \DateTimeZone('America/Chicago'));
$end = new \DateTimeImmutable('2022-06-06 11:00:00.000000', new \DateTimeZone('America/New_York'));
$result = getYearsBetween($start, $end);
var_export($result);

Resulted in this output:

-22

But I expected this output instead:

21

There seems to be a timezone issue that breaks \DateIntervals
Works (same time zones): https://3v4l.org/RK34h
Does not work (different time zones): https://3v4l.org/nmPAj

In the mean time, I will be ensuring both \DateTimeImmutables are in the same timezone before calling ->diff()

PHP Version

>= 8.1.10

Operating System

No response

@jack-worman jack-worman changed the title Bug introduced in PHP 8. Time zone bug with \DateTimeInterface::diff() Nov 1, 2022
@heiglandreas
Copy link
Contributor

That looks like the documentation of the parameter absolute is a bit ... off?

@hormus
Copy link
hormus commented Nov 4, 2022
The return value more specifically represents the clock-time interval to apply to the original object ($this or $originObject) to arrive at the $targetObject. This process is not always reversible.

Without absolute

<?php

$start = new \DateTime('2000-11-01 09:29:22.907606', new \DateTimeZone('America/Chicago'));
$end = new \DateTime('2022-06-06 11:00:00.000000', new \DateTimeZone('America/New_York'));
$result = $start->diff($end);
var_export($result->y);

?>

Yes bug, DateTimeImmutable from php 5.5.0, diff from php 5.3.0 expected result is 21.

<?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, $dateDiff->format('%r%a'));

?>

Expected result: (only 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)
}
string(3) "-58"

Expected result $dateDiff = $test1->diff($test2): (only 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)
}
string(2) "58"

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

5 participants