2013-10-18 24 views
0

在我的 「工具箱」 我使用這個功能:PHP:(!時間戳Y2038錯誤認識)管理的DateTime正道

function dataAttuale() { 
    $now     = new DateTime(); 
    $dataAttuale   = $now->format(DateTime::ISO8601); 
    $offset     = $now->getOffset(); 
    date_default_timezone_set('UTC'); 
    $nowUTC    = new DateTime(); 
    $dataUTC    = $nowUTC->format(DateTime::ISO8601); 
    $orario    = array(); 
    $orario['dataAttuale'] = $dataAttuale; 
    $orario['dataUTC']  = $dataUTC; 
    $orario['offset']  = $offset; 
    return $orario; 
} 

我得到這個數組

Array 
(
    [dataAttuale] => 2013-10-18T11:03:52+0200 
    [dataUTC] => 2013-10-18T09:03:52+0000 
    [offset] => 7200 
) 

所以我可以在日期時間MySql字段中保存一個日期時間,稱爲UTC。

現在,我對此有些麻煩。

1)我會保存也抵消(以秒爲單位)。 什麼是最好的Mysql字段?我認爲最大秒數可以是+ 14小時* 60 * 60 = 50400和-12小時* 60 * 60 = -43200

2)您認爲值得注意的還有抵消嗎?即,例如,多個API服務以UTC +偏移量返回日期...

非常感謝!

更新:

謝謝你們兩個人。現在我以UTC格式和varchar時區保存在MySQL日期時間中。一對夫婦的代碼,我得到了我想要的:

$orario = new DateTime($value['creazione'], new DateTimeZone($value['timezone'])); 
$orario  = $orario->format(DateTime::ISO8601); 

輸出是(歐洲/羅馬)

2013-10-19T09:27:54+0200 

而對於美國/蒙特利爾

2013-10-19T09:29:16-0400 

而對於澳大利亞/墨爾本

2013-10-19T09:30:31+1100 

(差異分鐘//秒,在我的PHP腳本中更改默認時區)。

現在我認爲:

1)我可以笑一下Y2038錯誤,放棄(:(嘆氣)日期和時間:(

2)我可以放心地周遊世界,用我自己的日曆( naaaa ......我會永遠使用谷歌日曆,當然)

回答

1

MySQL是時區的(它不存儲與日期的時區,但其轉換爲標準化的格式),所以大部分的您不需要額外的字段與偏移量。

您只需確保爲連接設置了正確的time_zone

所以,如果你有個約會,你想將其存儲在數據庫中,你有不同的可能性:

  1. 您可以使用SET time_zone = timezone;爲您的連接。你告訴MySQL,你發送或接收來自MySQL的日期應該在給予timezone。 MySQL會在內部將其轉換爲標準格式。

  2. 如果要插入具有不同時區的日期,然後設置爲time_zone,則可以使用CONVERT_TZ(dt,from_tz,to_tz)from_tz是您的日期的時區,to_tz是爲您的連接設置的時區。

有肯定的情況下的時區也無所謂。如果這是真的,你的情況並不完全清楚你的問題。

+0

如果我發送一個INSERT查詢到MySQL與UTC日期,我也需要先用SET TIME_ZONE =「+00:00」,還是因爲我的日期是在尚未UTC我並不需要它? – sineverba

+1

@sineverba這取決於你的MySQL設置(通常系統設置正在使用,但你不能依賴它)。就我個人而言,我總是爲每個MySQL連接設置'charset'和'time_zone'來與我使用的'charset'和'time_zone'連接。這樣我就不必擔心如果_correct_ one被設置爲配置文件。 –

+0

我爲每個連接設置charset爲UTF8。從現在開始,我還會設置timezone ='+00:00'。謝謝! – sineverba

1

保存偏移量沒有多大意義。還有你可以用一個時間戳感興趣的兩個可能的值:

  1. 一般全局時間戳,例如「在這個世界上的時間點,它是上午12點52分在2013年9月6日UTC」
  2. 在時間上的具體本地某個時間點,例如「17:34上二○一二年十二月一十九日在菲律賓馬尼拉」

注意,這兩個其實都是一樣的東西,他們表達時間的掛鐘時間和日期符號一個點,在一個特定的位置或時區。唯一的區別是UTC是一個指定的標準「位置」,相對於其他時區偏移量的表達方式;但菲律賓的馬尼拉沒有理由不能用於相同的目的。

所以,當你想存儲的絕對時刻,您:

  1. 決定你所有的時間都存儲在像UTC特定的時區,並簡單地存儲時間戳
  2. 決定你有興趣特定的本地時間與存儲的時間戳和時區,你需要的時間戳

無論哪種方式,你需要知道哪個時區是在在1.你事先知道所有的決定時間戳在同一個定義的時區中,並且不需要存儲它,在2中,您明確地保存該時區信息。

一個偏移量是不是一個好東西存儲,因爲它在一年中變化。夏季的偏移量對於UTC可能是+6小時,但在冬季可能是+7。如果您以後需要在本地化時間進行日期計算,則抵消是誤導性的,對您沒有多大幫助。如果您知道您正在討論的時區,則可以在稍後的一年中的任何時間獲得抵消。

MySQL不支持DATETIME + TIMEZONE字段(例如Postgres),因此您需要將時區(例如「Europe/Berlin」)存儲在單獨的文本字段中。如果根本不需要將時間戳與特定位置相關聯,則不需要時區,而只需存儲規範化時間戳,例如,規範化爲UTC。

+0

因此,您的提示是「不保存偏移量,但如果您需要將時間戳// UTC時間與給定時區關聯保存在varchar時區名稱(例如」Europe/Rome「)中? – sineverba

+0

是的,確切地說。如果您需要時區,請保存時區,而不是偏移量。始終與時區一起工作,永遠不會偏移。 – deceze

+0

謝謝。你能用新的DateTime函數PHP5來解決我從時區檢索「偏移量」嗎?如果我有UTC的日期和「歐洲/羅馬」時區,那麼應用+2的功能是什麼? – sineverba