php - PHP:转换后一小时从 Dailight Savings Time 中减去 1 小时
问题描述
我在 PHP 中遇到了一件奇怪的事情。在时区中,Europe/Oslo
我从时间戳中减去了一小时2020-03-29 03:00:00
(这正是 Dailight Savings Time shift 发生的时间),结果是完全相同的时间戳2020-03-29 03:00:00
!它应该导致2020-03-29 01:00:00
. 怎么没有?
一直到2020-03-29 03:59:59
它在减去一小时时返回完全相同的时间戳(尝试了sub()
和modify()
)。之后的下一秒,它正确地导致2020-03-29 03:00:00
.
你可以像这样重现它:
date_default_timezone_set('Europe/Oslo');
echo (new \DateTime('2020-03-29 03:00:00'))->sub(new \DateInterval('PT1H'))->format('Y-m-d H:i:s');
我已经在 PHP 7.1.33、7.3.10 和 7.3.18 中对此进行了测试。
PS。增加 1 小时2020-03-29 01:00:00
确实可以正确给出2020-03-29 03:00:00
。
解决方案
虽然我同意这是不良/错误的行为,但您可以通过严格只在 UTC 中存储或计算日期来避免它。考虑时区仅用于显示目的,您将避免很多麻烦。
例如:
// input
$utc = new DateTimeZone('UTC');
$user_tz = new DateTimeZone('Europe/Oslo');
$input = new DateTime('2020-03-29 03:00:00', $user_tz);
$storage = (clone $input)->setTimezone($utc);
var_dump(
$input->format('c'),
$storage->format('c')
);
// compute
$interval = new DateInterval('PT1H');
$storage->sub($interval);
var_dump(
$storage->format('c')
);
// display
$display = (clone $storage)->setTimezone($user_tz);
var_dump(
$display->format('c')
);
输出:
string(25) "2020-03-29T03:00:00+02:00"
string(25) "2020-03-29T01:00:00+00:00"
string(25) "2020-03-29T00:00:00+00:00"
string(25) "2020-03-29T01:00:00+01:00"
推荐阅读
- java - 在 SpringApplicationRunListener.starting 中禁用信息记录
- javascript - “本地主机拒绝连接”与 npm start
- node.js - Discord Bot 将消息从 udp 连接发送到特定通道
- python - 为什么 replace() 函数不起作用?
- ios - 使用 TestFlight 进行“内部分发”
- r - 在 Azure Webapp 上运行 R 程序
- python - Python 日期时区格式
- r - R - 将计算值添加到矩阵
- php - 如何在没有 Doctrine 实体的情况下使用 FOSElastica 从目录中索引文件
- bash - 在 shell 中使用 /bin/bash -ac 在容器 shell 中运行原始命令 VS 命令,但结果不一样