2014-04-03 52 views
1

我的數據庫服務器的TIMEZONE是UTC。我有不同的時區與數據庫交互的Java服務器。天真地我發現,如果我有一個TIMESTAMP字段,我真的沒有辦法將它從Java服務器的JPA代碼中設置爲UTC。我想我天真地認爲,如果JDBC總是發送TZ信息的日期,並且數據庫服務器可以基於它的時區適當地轉換或者轉換。但不是。 (地理位置分散的服務器,PostgreSQL和JPA

這裏有一些問題,我可能在不同的時區與這個數據庫服務器交互的Java服務器如果東海岸的晚上9點和西岸的晚上6點發生什麼事情,我希望這兩個事件都存儲在數據庫在同一時間,對吧?

那麼有什麼解決方案,我想我可以把所有的Java服務器都放在UTC中,但似乎應該有一個不太重的解決方案,我想我也可以設置時區在每一筆交易,但呃

我知道我會得到一些答案,說我應該只在數據庫中存儲多頭,雖然我很欣賞這個答案的真實性,我想保留TIMEZONE和我的數據庫表中的DATE字段。所以我正在尋找其他類型的答案。謝謝。

+0

不要忘記使用NTP同步時鐘 – Leo

+0

我認爲您希望'timestamp with時區「,而不是」時間戳「。如果您還希望保留時區/偏移量,則必須單獨存儲它 - 具有時區類型的時間戳的命名在這方面是相當具有欺騙性的。感謝SQL標準。 –

+0

如果postgres服務器在UTC中運行,這會如何改變? –

回答

1

解決方法是及時爲這些時刻使用TIMESTAMPTZ字段。類似於「用戶創建時間」的內容不應該與TIMESTAMP字段一起存儲,因爲默認情況下它不包含TZ信息。 JDBC驅動程序處理這些非常任意。例如,請考慮以下內容:

假設您的JVM位於America/Los_Angeles區域,而數據庫服務器位於UTC。

然後創建下表:

CREATE TABLE test (
    id INTEGER, 
    ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
    tswz TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 
); 

如果從PSQL發出:

INSERT INTO test(id) values(1); 

您將得到相同的值, 「TS」 和 「tswz」。兩者都是當前UTC時間。但是,如果使用JDBC驅動程序從Java執行SAME EXACT查詢,則「ts」將是洛杉磯當前時間,「tswz」將是UTC時間。

我不知道在這種情況下,驅動程序如何傳遞到服務器的JVM時區,因爲我們默認服務器上的字段。他們說他們沒有設置會話的時區,但他們必須。無論哪種方式,如果使用TIMESTAMPTZ字段,那麼無論發生什麼時區,都可以從任何JVM獲得相同的時刻。