2016-11-10 76 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 
     ) 

)