2016-11-10 74 views
0

我很难理解我的代码如何适应DST,因为它最近的更新不正确。我将日期时间存储在基于UTC的数据库中,然后将其转换回本地时区进行显示。如果PHP考虑到DST,则其他事情是错误的,因为我所有的存储日期都是1个小时。PHP和DST转换问题

$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类中自动得到补偿。

这些时区之间
+2

那岂不小时的时差表示DST的变化是什么哟你会期待什么?我不确定你期望的不同。 –

+0

结果应该是2016-11-16 08:04:01不管DST是否生效。我假设当PHP从UTC转换到另一个时区时,它会知道DST是否有效并产生相同的本地时间。也许答案是,PHP在技术上做的是正确的事情,我需要通过调整DST来弥补我的商业案例。 –

+0

该日期* * DST更改后*因此它永远不应该是2016-11-16 08:04:01。 DST更改前的日期应该是08:04:01但不是之后。 –

回答

0

纽约市开关:

  • 冬季: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 
     ) 

)