奇怪的行为 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
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