Skip to content

DateTime::diff doesnt evaluate daylight saving time correctly #9382

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

Closed
chaosben opened this issue Aug 19, 2022 · 4 comments
Closed

DateTime::diff doesnt evaluate daylight saving time correctly #9382

chaosben opened this issue Aug 19, 2022 · 4 comments

Comments

@chaosben
Copy link

Description

The following code:

<?php

$dt1 = new DateTime('2022-08-01 07:00:00', new DateTimeZone('Europe/Berlin'));
$dt2 = new DateTime('2022-08-01 07:00:00 +02:00');

echo "DT1: {$dt1->format('c')}" . PHP_EOL;
echo "DT2: {$dt2->format('c')}" . PHP_EOL;

$diff = $dt1->diff($dt2);

echo "Diff: {$diff->format('%h')}";

Resulted in this output:

DT1: 2022-08-01T07:00:00+02:00
DT2: 2022-08-01T07:00:00+02:00
Diff: 1

But I expected this output instead:

DT1: 2022-08-01T07:00:00+02:00
DT2: 2022-08-01T07:00:00+02:00
Diff: 0

According to https://3v4l.org/eOUP5 this bug exists since PHP 8.1.0

PHP Version

PHP 8.1.9

Operating System

Fedora 36

@cmb69
Copy link
Member

cmb69 commented Aug 19, 2022

Indeed, that looks wrong to me.

@hormus
Copy link

hormus commented Aug 20, 2022

@cmb69 @derickr forgot to add a note in the manual for diff, if they are with timezone type int 3 the result is effective otherwise if different timezones will be converted to UTC and calculate the difference. if you need I will send you when diff has been modified.

yes it's a bug for me too

Valid period transitions:

<?php

date_default_timezone_set('Europe/Berlin');
$origin = new DateTime('2022-03-27 02:00:00', new DateTimeZone('Europe/Berlin'));
$target = new DateTime('2022-03-27 02:00:00 +0200');
$origin->setTimeZone(new DateTimeZone('Europe/Berlin'));
$origin = new DateTime($origin->format('Y-m-d H:i:s'), new DateTimeZone('Europe/Berlin'));

$simil_utc = $target->format('Y-m-d H:i:s');
$target = new DateTime($simil_utc, new DateTimeZone('Europe/Berlin'));
$target->setTimeZone(new DateTimeZone('Europe/Berlin'));
$target = new DateTime($target->format('Y-m-d H:i:s'), new DateTimeZone('Europe/Berlin'));
$interval = $origin->diff($target);

echo $interval->format('%R%a days %h hours') . "\n";
var_dump($origin, $target);

?>

DateTime::Diff php 8.10 > if object same type offset timezone $origin and $target is local time object. Means for DST +0200: Europe/Berlin = Europe/Berlin or Europe/Berlin = +0200 or Europe/Berlin = CEST (ex. Localtime object 2022-03-27 02:00:00 - 2022-03-27 02:00:00 = 0 or 2022-03-27 03:00:00 - 2022-03-27 03:00:00 = 0 or Europe/Berlin = +0200 2022-03-27 03:00:00 - 2022-03-27 02:00:00 = 0), for Europe/Berlin: ST (+0100) and DST (+0200) 2022-03-27 01:00:00 - 2022-03-27 03:00:00 = 1 or 2022-03-27 01:00:00 - 2022-03-27 02:00:00 = 1
Note* for ST type 3 and DST type 1: besides the bug mentioned Diff does not support several transitions. In all other cases it converts it to UTC.
DateTime::Diff php 5.3.0 < php 8.1.0 $origin and $target is UTC object. Europe/Berlin to UTC. Means: (ex. UTC object 2022-03-27 01:00:00 - 2022-03-27 01:00:00 = 0)

@derickr
Copy link
Member

derickr commented Aug 25, 2022

This seems to be already fixed in the 8.1.10RC1. I can successfully recreate this with 8.1.9, but not with 8.1.10RC1. I believe it is a duplicate of #8730.

@chaosben
Copy link
Author

🥳 Thanks!

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

4 participants