2012-08-23 19 views
2

這應該很簡單,但我有一個令人尷尬的數量的麻煩。有沒有一種簡單而乾淨的方法可以在UTC的午夜時間將`DATE`轉換爲該日期的`TIMESTAMP AT TIME ZONE`?

在PostgreSQL 9.1中,我需要在DB中解釋一個存儲爲DATE的字段,就好像它是代表該日期的午夜UTC的TIMESTAMPTZ一樣。我希望以一種乾淨可讀的方式做到這一點,即有人可以前來參觀,瞭解發生的事情。

到目前爲止我發現的唯一方法是非常難看。一個將其轉換爲TIMESTAMP WITHOUT TIME ZONE通過解釋它,就好像它是UTC創建一個從它TIMESTAMP WITH TIME ZONE

SELECT CAST(DATE '2012-01-01' AS TIMESTAMP WITHOUT TIME ZONE) AT TIME ZONE 'utc' 

另一種方式是更糟:

('2012-01-01'::date)::timestamptz - (current_timestamp AT TIME ZONE 'UTC' - current_timestamp) 

,它的日期轉換爲時間戳本地時間午夜,然後減去時區偏移量。我無法找到任何方法將本地時間間隔作爲間隔(這看起來很瘋狂),所以我通過比較本地時間的current_timestamp與UTC中的current_timestamp來得到它。

我唯一能解決的另一個方法是使用extract來獲取日期部分並從它們中組裝一個新的timestamptz。我甚至不會表明那個,這太難看了。

這兩種方法都會感到各種奇怪和錯誤。有沒有什麼合理的方法 - 標準的還是沒有的 - 在當天UTC的午夜時間以易讀易懂的方式將其從DATE轉換爲timestamptz

我正在尋找像(假想的,將無法正常工作)

'2012-01-01'::date AS TIMESTAMPTZ IN TIME ZONE '00:00'; 

to_timestamp('2012-01-01'::date, '00:00'::time, 'UTC'); 

請指出我錯過了愚蠢明顯的事情。

請注意,我正在測試以確保內部日期真正正確,而不僅僅是在顯示屏上,其中其中$1是轉換日期。

回答

4

你的第一種方法是正確的。這不是很難看,是嗎?在簡化Postgres的語法:

SELECT '2012-1-1'::date::timestamp AT TIME ZONE 'UTC'; 

適用於一個變量或列看起來更優雅:

SELECT mydate::timestamp AT TIME ZONE 'UTC'; 

如果你要手動輸入日期,您可以通過快捷鍵來:

SELECT '2012-1-1 0:0'::timestamp AT TIME ZONE 'UTC' 

根據客戶端的本地時區(即與相應的偏移量),結果將始終顯示爲,但這沒有影響e在的值

+0

我試圖避免'TIMESTAMP'類型,因爲它的奇怪而且往往是醜陋的行爲,但如果這是做好這項工作的最好方法。謝謝。 –

+0

通過將'時間戳'加入'AT TIME ZONE'UTC'',您可以立即將醜小鴨變成'timestamptz',永遠不必面對醜陋。 :) –

+1

是的,我想是的。我只是很驚訝,似乎有必要使用'timestamp'來執行'timestamptz'這樣的操作。它會讓'timestamptz'感覺不足或不完整。在這個過程中,我注意到文檔似乎沒有提到將'date'轉換爲'timestamptz'是否會產生本地時間或utc(可能有意義),所以我必須爲此提出一個文檔補丁。 –

2

注意:我對PSQL不太瞭解,但是我有一些日期/時間方面的經驗。

你的第一種感覺對我來說很合適。從「本地日期」到「本地日期/時間」到「在特定時間段內的日期/時間」,您實際上會有所變化。這些都是合理的步驟,以及我期望在正常日期/時間API中看到的步驟。

就我所知,這種方法從來沒有引入系統默認時區,這是一件非常好的事情。它一次執行一個合乎邏輯的步驟,假設投下了合理的東西。

由於UTC沒有任何DST轉換,您不必擔心目標時區中的本地日期/時間不明確或缺失。

基本上,它看起來很好。如果它能夠正常工作並且表現得很好,我會堅持下去。

+1

客戶端的當前時區只涉及渲染結果,將根據它顯示結果。它不會影響價值。 –

+0

@ErwinBrandstetter:這就是我的觀點 - 這裏不介紹其他時區是件好事。 –

+1

我同意。有些人可能會感到困惑,因爲他們*看到當地時區對結果的影響 - 但價值本身不受影響。 –

相關問題