PHP DateTime and DateTimeZone works incorrectly for me around DST change dates.
I wrote a simple function to convert local time to UTC and I called it with the midnight time from the 24th of Oct to the 2nd of Nov with the timezones Europe/Paris and CET:
<?php
function timeToUTC($time, $timeZone, $format='Y-m-d H:i:sP')
{
$dt = new DateTime($time, new DateTimeZone($timeZone));
$dt->setTimeZone(new DateTimeZone('UTC'));
return $dt->format($format);
}
$localTimes = [
'2020-10-24 00:00:00',
'2020-10-25 00:00:00',
'2020-10-26 00:00:00',
'2020-10-27 00:00:00',
'2020-10-28 00:00:00',
'2020-10-29 00:00:00',
'2020-10-30 00:00:00',
'2020-10-31 00:00:00',
'2020-11-01 00:00:00',
'2020-11-02 00:00:00',
];
foreach (['Europe/Paris', 'CET'] as $timeZone) {
echo "******** $timeZone ********" . PHP_EOL;
foreach ($localTimes as $localTime) {
$utcTime = timeToUTC($localTime, $timeZone);
echo "$localTime $utcTime" . PHP_EOL;
}
}
The output:
******** Europe/Paris ********
2020-10-24 00:00:00 2020-10-23 22:00:00+00:00
2020-10-25 00:00:00 2020-10-24 22:00:00+00:00
2020-10-26 00:00:00 2020-10-25 23:00:00+00:00
2020-10-27 00:00:00 2020-10-26 23:00:00+00:00
2020-10-28 00:00:00 2020-10-27 23:00:00+00:00
2020-10-29 00:00:00 2020-10-28 23:00:00+00:00
2020-10-30 00:00:00 2020-10-29 23:00:00+00:00
2020-10-31 00:00:00 2020-10-30 23:00:00+00:00
2020-11-01 00:00:00 2020-10-31 23:00:00+00:00
2020-11-02 00:00:00 2020-11-01 23:00:00+00:00
******** CET ********
2020-10-24 00:00:00 2020-10-23 23:00:00+00:00
2020-10-25 00:00:00 2020-10-24 23:00:00+00:00
2020-10-26 00:00:00 2020-10-25 23:00:00+00:00
2020-10-27 00:00:00 2020-10-26 23:00:00+00:00
2020-10-28 00:00:00 2020-10-27 23:00:00+00:00
2020-10-29 00:00:00 2020-10-28 23:00:00+00:00
2020-10-30 00:00:00 2020-10-29 23:00:00+00:00
2020-10-31 00:00:00 2020-10-30 23:00:00+00:00
2020-11-01 00:00:00 2020-10-31 23:00:00+00:00
2020-11-02 00:00:00 2020-11-01 23:00:00+00:00
For Europe/Paris
I got the changed DST instead of the 31st of October at the 26th. And even worth that there is no change at all for the timezone CET
.
What do I wrong? Is it about a PHP bug?
It's about PHP on Ubuntu. I tried Ubuntu 16.04 with PHP 7.2.34-8 and Ubuntu 18.04 with 7.2.24-0.
The output is correct.
France switched to winter time October 25th, and most abbreviation timezones like CET don't have DST rules.
Countries like France are in CET 6 months out of the year, and CEST the other 6. The abbreviated timezones are confusing, so generally I just recommend people to not use them.
echo (new DateTime('2020-10-01', new DateTimeZone('Europe/Paris')))->format('T'), "\n";
echo (new DateTime('2020-11-01', new DateTimeZone('Europe/Paris')))->format('T'), "\n";
Output:
CEST
CET