簡體   English   中英

來自Java程序的HSQLDB中的UTC Unix時間戳存儲在錯誤的時區

[英]UTC Unix timestamp storage in HSQLDB from Java program in wrong timezone

我試圖了解如何在HSQLDB嵌入式文件數據庫中存儲Unix時間戳 (即自1970年以來在UTC / GMT時區中表示的秒數)。 但是,我還沒有理解TZ處理如何與HSQL一起使用。

我的程序將在不同的區域使用,因此使用UTC是必須的。 此外,我無法更改默認時區(與java.util.TimeZone.setDefault ),因為它將嵌入其他程序中,因此不應更改環境。

我的嘗試 - 文件指出:

使用PreparedStatement或CallableStatement接口將datetime值發送到數據庫時,Java對象將轉換為ready或callable語句參數的類型。 此類型可以是DATE,TIME或TIMESTAMP(帶或不帶時區)。 時區位移是JDBC會話的時區。

所以我在數據庫中使用了TIMESTAMP列(沒有時區 - 默認值),並發出SET TIME ZONE INTERVAL '0:00' HOUR TO MINUTE (將會話置於UTC TZ中)然后INSERT INTO TEST VALUES(?)用? 是一個包含正確Unix值的Java Timestamp對象(GMT相關,測試正常)。

遺憾的是,在這種情況下,數據庫的SQL日志顯示時間戳已恢復為我的本地時區(+2)。 對於1442132237635的時間戳(UTC中的8H17,+ 2中的10H17),我們在日志中得到TIMESTAMP'2015-09-13 10:17:17.602000' 錯誤的結果......似乎改變會話時區絕對沒有任何影響(我已經嘗試過+14,-14 ......沒有變化)。 然而,SET順序正確執行 - 它出現在SQL日志中,TIMEZONE()的值隨后發生變化。

其他嘗試

我還嘗試使用TIMESTAMP WITH TIME ZONE列,而不設置會話TZ。 在這種情況下,數據庫存儲'本地時間+2',我可以從中提取正確的時間戳。 這是邊緣荒謬 - 這意味着HSQLDB驅動程序采用Java時間戳(UTC),將其正確解釋為UTC,將其轉換為JVM默認TZ,然后將其發送到DB。 我不想要數據庫中的TZ信息 - 不需要它。 (注意:改變會話TZ沒有影響 - 發出的SQL命令總是與我的本地TZ ...讓你想知道SET TZ命令的重點是什么)

並將默認的JVM TZ更改為UTC,但如上所述我不能這樣做。

另外值得注意的是: 這個問題似乎有關,但提供的答案基本上是破解我想避免的每個SQL命令......

我的問題

如何將我的UTC Java時間戳存儲在HSQLDB中? SET TIME ZONE訂單的目的是什么?

謝謝閱讀。

您的第一次嘗試是正確的,並將返回正確的結果。

您的數據庫位於UTC + 2時區。 您正在連接,就像您是UTC時區中的遠程用戶一樣。

您聲明時間戳的日志存儲沒有錯誤。 日志存儲不是供數據庫用戶讀取的。 數據庫將其日志存儲在您所在位置的時區中。 下次讀取日志時,它會根據您的數據庫時區讀取並解釋它(與會話時區無關)。 因此,以10:17存儲在日志中的時間將是UTC中的8:17。

使用TIMESTAMP WITHOUT TIME ZONE,數據庫文件無法移動到其他時區,因為時間戳將根據新位置的區域進行解釋。

SET TIME ZONE語句的作用是允許在存儲數據時進行正確調整。 它不會更改以前存儲的數據。 當然,如果時間存儲為8:17,則無論何時以及在任何訪問區域,都應將其讀取為8:17。

為了獲得最佳便攜性,請使用TIMESTAMP WITH TIME ZONE。 即使您移動數據庫文件,它存儲和檢索數據的方式也是正確的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM