【问题标题】:PHP and DST conversion issuePHP 和 DST 转换问题
【发布时间】:2017-03-24 19:47:15
【问题描述】:

我无法理解我的代码如何适应 DST,因为最近的更新不正确。我根据 UTC 在数据库中存储日期时间,然后将其转换回本地时区以进行显示。如果 PHP 将 DST 考虑在内,还有其他问题,因为我存储的所有日期都是 1 小时。

$stored_date = '2016-11-16 12:04:01'; // in UTC

$dateTime = new DateTime($stored_date, new DateTimeZone('UTC'));
$dateTimeZone = new DateTimeZone('America/New_York');
$dateTime->setTimezone($dateTimeZone);

print_r($dateTime);

上周,在 DST 结束之前,这将打印出 2016-11-16 08:04:01。本周,既然 DST 已经结束,它会打印 2016-11-16 07:04:01。如果 PHP 正确处理 DST 班次,为什么会有小时差?

服务器设置无关紧要(我不这么认为),因为我明确地在 PHP 中进行转换,对吧?

我已准备好开始使用 PHP 检查 DST 是否生效并将转换偏移 1 小时,因为我无法弄清楚为什么在 DateTime 类中没有自动补偿该小时。

【问题讨论】:

  • 这个小时差不代表 DST 的变化,这是您所期望的吗?我不确定您期望会有什么不同。
  • 无论夏令时是否生效,结果都应该是 2016-11-16 08:04:01。我假设当 PHP 从 UTC 转换到另一个时区时,它会知道 DST 是否有效并产生相同的本地时间。也许答案是 PHP 在技术上做的是正确的事情,我需要通过调整 DST 来弥补我的业务案例。
  • 那个日期是 DST 更改之后,所以它不应该是 2016-11-16 08:04:01。 DST 更改之前的日期应该是 08:04:01,而不是之后。
  • 明白了,有道理。
  • 我们在 11 月“回退”,所以时间更改之前的 08:04:01 应该是之后的 07:04:01Americas/New York 从 -4 变为 -5。我认为这里没有问题。

标签: php timezone dst


【解决方案1】:

纽约市在这些时区之间切换:

  • 冬季:EST(东部标准时间)= UTC -5
  • 夏季:EDT(东部夏令时间)= UTC -4

timeanddate.com 称,转换将在 11 月 6 日进行。因此结果是正确的:12 - 5 = 7

换句话说,PHP 完全了解 DST,我们可以在以下代码中看到:

$dateTime = new DateTime('2016-11-05 12:04:01', new DateTimeZone('UTC'));
$dateTime->setTimezone(new DateTimeZone('America/New_York'));
echo $dateTime->format('r') . PHP_EOL;

$dateTime = new DateTime('2016-11-06 12:04:01', new DateTimeZone('UTC'));
$dateTime->setTimezone(new DateTimeZone('America/New_York'));
echo $dateTime->format('r') . PHP_EOL;
Sat, 05 Nov 2016 08:04:01 -0400
Sun, 06 Nov 2016 07:04:01 -0500

您可以检查系统时间数据库中可用的确切信息:

$timeZone = new DateTimeZone('America/New_York');
print_r($timeZone->getTransitions(mktime(0, 0, 0, 1, 1, 2016), mktime(0, 0, 0, 12, 31, 2016)));
Array
(
    [0] => Array
        (
            [ts] => 1451602800
            [time] => 2015-12-31T23:00:00+0000
            [offset] => -18000
            [isdst] => 
            [abbr] => EST
        )

    [1] => Array
        (
            [ts] => 1457852400
            [time] => 2016-03-13T07:00:00+0000
            [offset] => -14400
            [isdst] => 1
            [abbr] => EDT
        )

    [2] => Array
        (
            [ts] => 1478412000
            [time] => 2016-11-06T06:00:00+0000
            [offset] => -18000
            [isdst] => 
            [abbr] => EST
        )

)

【讨论】:

    猜你喜欢
    • 2016-01-31
    • 2013-09-29
    • 2011-12-22
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 2013-11-17
    相关资源
    最近更新 更多