Open Geekimo opened 1 month ago
It's not a bug. You can set manual convert to UTC (DST or ST Europe/Paris +2 or +1)
<?php
$timezone = new \DateTimeZone('UTC');
$periodStart = (new \DateTimeImmutable('2024-10-20 22:00:00', $timezone));
$periodEnd = (new \DateTimeImmutable('2024-10-27 22:59:59', $timezone));
$timezone = new \DateTimeZone('Europe/Paris');
$periodStart = $periodStart->setTimezone($timezone);
$periodEnd = $periodEnd->setTimezone($timezone);
var_dump($periodStart->diff($periodEnd)->format('%y years %m months %a days %H hours %I minutes %s seconds'), $periodEnd->setTimezone(new DateTimeZone('UTC')));
?>
From PHP >= 8.2.6 expected result:
string(54) "0 years 0 months 6 days 23 hours 59 minutes 59 seconds"
object(DateTimeImmutable)#5 (3) {
["date"]=>
string(26) "2024-10-27 22:59:59.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
Or from PHP < 8.2.6 expected result:
string(54) "0 years 0 months 6 days 24 hours 59 minutes 59 seconds"
object(DateTimeImmutable)#5 (3) {
["date"]=>
string(26) "2024-10-27 22:59:59.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
It's never 7 days.
@hormus I don't get your point. With the same timezone. If I set a period, which has between his bounds a transition from winter to summertime, calculation is correct. If I do the same transition, but from summertime to winter time, calculation is incorrect. How could this not be a bug ? Europe/Paris is a type 3 timezone, which according to https://wiki.php.net/rfc/datetime_and_daylight_saving_time has proper calculation rules, which should be applied in the current case.
Hi @Geekimo, the interval from 00:00:00 to 23:59:59 is 23:59:59 if with UTC time zone. If with forward transition "start daylight saving time" 02:00:00 is 03:00:00 local time.
02:00:00 does not exist for "daylight saving time". So applying this formula from 00:00:00 to 23:59:59 "24:59:59 hours DST end" -01:00:00 is 23:59:59.
@hormus Ok, so you didn't get my point. Let me reformulate, it may be clearer this way. 😅
I have a recurring task, each week, where I need to have the exact number of years, months, days, hours, minutes and seconds between monday 00:00:00 and sunday 23:59:59, because it matters to my task.
On traditional weeks, like the previous one, which has no DST transition, I have 0 years 0 months 6 days 23 hours 59 minutes 59 seconds
, which is perfectly normal, and is the result that I await.
When, I have a DST transition, from winter time to summer time, the same exact code will return 0 years 0 months 6 days 22 hours 59 minutes 59 seconds
. This is what I expect this code to do and it's perfectly normal, as we remove one hour in this particular week.
Then, when I have the opposite DST transitoin, from summer time to winter time, like this week, the same exact code will return 0 years 0 months 6 days 23 hours 59 minutes 59 seconds
, like there was no transition. This is not what I expect this code to do, because we add one hour in this particular week. (At 3 o'clock on sunday morning, it's 2am again).
What should happen is that my code should return 0 years 0 months 7 days 0 hours 59 minutes 59 seconds
.
If you look closely at the code I provided, I apply the timezone before changing time, and setting timezone as seconde parameter of \DateTimeImmutable::__construct(...)
has no impact.
Description
The following code:
Resulted in this output:
But I expected this output instead:
I did the same test using winter to summer time switch and the result is good.
Output:
3v4l.org links:
PHP Version
PHP 8.2.21 and up
Operating System
No response