2009-10-13 46 views
5

我一直在閱讀關於如何在整個上午完成此操作的問題,並且普遍的一致意見是:將您的時間戳存儲在UTC並計算從那裏的偏移量。在不使用UTC的情況下顯示時間戳

然而,像大多數人一樣,我維護着一個現有的代碼庫,我無法改變我們存儲日期的方式。至少,不在分配的時間範圍內。

所以我的問題是,我可以安全地做這樣的事情嗎?

// this is my time zone 
$timestamp = strtotime($timestampFromDatabase); 
date_default_timezone_set('America/New York'); 
$tz = date_default_timezone_get(); 

// this is theoretically their timezone, which will eventually 
// be taken from a session variable 
date_default_timezone_set('Europe/Paris'); 
$offset = time() - $timestamp; 
$timestamp -= $offset; 

// now that I have the offset, display dates like this 
date('r', $timestamp); 

有人建議不要做日期算術,但是我在這裏做的是錯的嗎?有沒有更好的辦法?我需要注意哪些缺陷?我特別感興趣的是這種方法可能產生什麼樣的錯誤,如果有的話,他們會影響誰?

我的老闆是那種不關心這個bug是否僅影響1%用戶羣的人。

編輯:我可以做得更清楚嗎?我似乎沒有太多的參與者。任何人?即使是一個模糊的建議或鏈接也是非常有用的。

回答

5

簡短的回答是,時區是棘手的工作,沒有人想解決難題!

的時間越長,答案是這樣的:

首先,你需要創建日期的表示,在他們目前的時區。以下是等價的:

date_default_timezone_set('America/New York'); 

$date = new DateTime(null); 

OR

$date = new DateTime(null, new DateTimeZone('America/New York')); 

這給你設置爲美國/紐約區的日期。我們可以很容易地將其轉換爲用戶的時區,在這種情況下,歐洲/巴黎與下一行:

$date->setTimezone(new DateTimeZone('Europe/London')); 

您可以使用下面的行獲得的任何一點表示的日期/時間。

echo $date->format('d/m/Y H:i:s'); 

強烈推薦這在算術,如內置的PHP函數具有日光節約時間和大量的複雜的東西,你不會得到正確的知識。在全


我的測試腳本:

date_default_timezone_set('America/Belize'); 

$date = new DateTime(null); 

echo $date->format('d/m/Y H:i:s') . '<br>'; 

$date->setTimezone(new DateTimeZone('Europe/London')); 

echo $date->format('d/m/Y H:i:s') . '<br>'; 
+0

你也可以用這種方法來更新數據庫,以UTC在一次性的工作以備將來使用。 – 2009-10-13 20:13:42

+0

這太棒了。但是,假設我運行PHP 5.14,它沒有這個對象。有另一種方法嗎? – 2009-10-13 20:32:17

+0

Zend Framework在Zend_Date中有一個基於PHP的解決方案,但要求PHP 5.2.4作爲框架的一般要求。它*可能*工作。你可以升級或重新編譯PHP嗎? – 2009-10-13 20:37:58