我在我們的 PostgreSQL 表中有一個日期欄位,其中保存了日期,包括時間戳和區域(捕獲時在 Java 端使用“localdatetime”)。但要求是只拉出日期部分的記錄檢查(忽略時區),以便世界各地的所有用戶按日期過濾都可以看到相同的結果。
請讓我知道我是否應該提供更多解釋。
uj5u.com熱心網友回復:
錯誤的資料型別意味著丟失資訊
保存日期的 postgres 表,包括時間戳和區域(捕獲時在 java 端使用“localdatetime”)
這是型別上的矛盾。
TIMESTAMP WITH TIME ZONEPostgreSQL 中的型別不保存時區。仔細閱讀檔案。它解釋了與日期和時間一起提供的任何時區或偏移量資訊用于調整到與 UTC 零時分秒的偏移量。換句話說,日期和時間被“調整為 UTC”,正如我們簡寫的那樣。
您可能提供的區域或偏移資訊隨后將被丟棄。Postgres 不記得原始偏移量或區域。從型別列中檢索的任何值TIMESTAMP WITH TIME ZONE始終采用 UTC。如果您關心原始區域或偏移量,則必須自己將其存盤在第二列中。
但是你有一個問題。將日期時間發送到資料庫時,您沒有提供任何時區或偏移量的指示符。您錯誤地使用了LocalDateTime故意缺少任何時區或偏移量指標的類。這個LocalDateTime類代表一個帶有時間的日期,沒有別的。于是就出現了上面提到的矛盾。您為需要三項內容(日期、時間和區域/偏移量)的列提供了兩項內容(日期、時間)。
我認為 Postgres 獲取了您的LocalDateTime值并將其存盤為 UTC 中的日期和時間。所以你丟失了資訊。例如,如果一行的輸入是在日本東京 ???? 的 2022 年 1 月 23 日中午,而另一行的輸入是在法國圖盧茲 ???? 的同一天的 23 日中午,而第三行的輸入本來也是在那個 23 日中午的,但正如在美國俄亥俄州托萊多 ???? 看到的那樣,那么您將錯誤地記錄三個不同的時刻,這些時刻相隔幾個小時發生,好像它們都發生在另一個時刻,第四時刻,23 日中午UTC 時間,2022-02-23T12:00Z。
在記錄了如此大量的錯誤值之后,就再也回不去了。除非您有辦法確定每行的預期區域,否則您的資訊將丟失,并且您存盤的列毫無價值。
查詢了一天
讓我們擱置無效存盤時刻的問題。現在讓我們關注如何使用型別為 的列查詢一天的行的問題TIMESTAMP WITH TIME ZONE。
您需要了解,對于任何給定時刻,日期因時區而異。澳大利亞悉尼????在任何時候都可能是“明天”,而在加拿大艾伯塔省埃德蒙頓????可能是“昨天”。因此,您需要時區(或偏移量)的背景關系來感知日期。
如果要查詢 Edmonton 中的某一天,請指定時區。
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
指定所需的日期。
LocalDate ld = LocalDate.of( 2022 , Month.JANUARY , 23 ) ;
確定代表當天所有時刻的時間跨度。定義這種跨度的最佳方法是半開方法。在半開中,開頭是包容的,而結尾是獨占的。因此,跨度從當天的第一時刻開始,一直到(但不包括)第二天的第一時刻。
為了開始一天,讓java.time確定。日子并不總是從 00:00 開始。
ZonedDateTime start = ld.atStartOfDay( z ) ;
ZonedDateTime end = ld.plusDays( 1 ).atStartOfDay( z ) ;
該ZonedDateTime不會映射到SQL任何資料型別。所以轉換成一個OffsetDateTime物件與資料庫交換。
OffsetDateTime odtStart = start.toOffsetDateTime() ;
OffsetDateTime odtEnd = end.toOffsetDateTime() ;
通過你準備好的宣告傳遞這些。
myPreparedStatement.setObject( … , odtStart ) ;
myPreparedStatement.setObject( … , odtEnd ) ;
在你的SQL,千萬不能使用BETWEEN。該命令已完全關閉。對于半開放,將 SQL 查詢撰寫為查找 (a)不在開始之前的值(“不在之前”是表示“等于或晚于”的縮寫方式),并且(b) 在開始之前結束。
uj5u.com熱心網友回復:
假設 24.12.2021 15:00 Berlin(德國)在資料庫中。
來自德國的人將看到 15:00。
但倫敦人必須看到 16:00 或“柏林的 15:00 掛鐘”。
既然你說
from all over the world can see the same resut
15:00 和 16:00 會有區別:數字 5 和數字 6,它們是不同的。
您可以通過列印為每個人提供相同的結果
15:00 wall clock in Berlin
但這需要在日期時間旁邊傳輸時區柏林。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/386169.html
標籤:爪哇 PostgreSQL的 jpa 弹簧数据-jpa
