奇怪的行为 PHP DateTime 和 DateTimeZone

Weird behavior PHP DateTime and DateTimeZone

PHP DateTime 和 DateTimeZone 在 DST 更改日期前后对我来说工作不正确。

我写了一个简单的函数来将本地时间转换为 UTC,我用 10 月 24 日到 11 月 2 日的午夜时间调用它,时区 Europe/Paris 和 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;
    }
}

输出:

******** 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

对于 Europe/Paris,我在 26 日收到更改后的 DST,而不是 10 月 31 日。甚至值得时区 CET.

完全没有变化

我做错了什么?是关于 PHP 错误吗?

Ubuntu 大约 PHP。我尝试 Ubuntu 16.04 与 PHP 7.2.34-8 和 Ubuntu 18.04 与 7.2.24-0.

输出正确。

法国在 10 月 25 日改为冬令时,大多数缩写时区(如 CET)没有 DST 规则。

像法国这样的国家一年中有 6 个月使用 CET,其他 6 个月使用 CEST。缩写时区令人困惑,所以通常我只是建议人们不要使用它们。

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";

输出:

CEST
CET