2 回答

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個贊
LocalDateTime從ZonedDateTime時區(qū)的簡單切割中獲取。它的價值無關(guān)緊要。您需要做的是將您的ZonedDateTime區(qū)域從+8 區(qū)轉(zhuǎn)換為+2 區(qū),這將相應(yīng)地改變時間。然后就可以LocalDateTime從你的修改中ZonedDateTime得到想要的效果了。這是一個演示它的示例:
private static void testDateParsing() {
ZonedDateTime zdt = ZonedDateTime.parse("2019-08-28T10:39:57+08:00", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZZZZZ"));
ZonedDateTime modifiedZdt = zdt.withZoneSameInstant(ZoneId.systemDefault());
System.out.println(zdt);
System.out.println(modifiedZdt);
System.out.println(LocalDateTime.from(zdt));
System.out.println(LocalDateTime.from(modifiedZdt));
}
輸出是:
2019-08-28T10:39:57+08:00
2019-08-28T05:39:57+03:00[Asia/Jerusalem]
2019-08-28T10:39:57
2019-08-28T05:39:57
請注意,我的本地時區(qū)是+03,而不是您的+02。

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超8個贊
? ? String text = "2019-08-28T10:39:57+02:00";
? ? OffsetDateTime time = OffsetDateTime.parse(text);
? ? System.out.println("Hour of day is " + time.getHour());
輸出是(如您所料):
一天中的小時是 10
嘗試不同的偏移量:
? ? String text = "2019-08-28T10:39:57+08:00";
一天中的小時是 10
所以仍然相同,仍然是字符串中給出的小時。這就是 10 的由來。我從你的代碼中選擇了一個稍微簡單的代碼示例,但它演示的行為與你的代碼相同,沒有區(qū)別,也足以解釋。
需要注意的一點(diǎn)是,代碼不依賴于 JVM 的時區(qū)設(shè)置(您報告為歐洲/巴黎)。那挺好的。這意味著,如果我們相信代碼是正確的,我們也可以相信它能夠在所有時區(qū)的所有 JVM 上正確運(yùn)行。
LocalDateTime在您的代碼中,您通過調(diào)用轉(zhuǎn)換為toLocalDateTime(). 通常這種轉(zhuǎn)換沒有任何充分的理由,因?yàn)镺ffsetDateTime或ZonedDateTime很好地實(shí)現(xiàn)了目的。OffsetDateTime轉(zhuǎn)換的作用是保留或中的日期和時間(掛鐘時間)ZonedDateTime并丟棄偏移量或時區(qū)信息。因此,如果一天中的小時在轉(zhuǎn)換前為 10,則轉(zhuǎn)換后也將為 10。如果您期望轉(zhuǎn)換為當(dāng)?shù)貢r間(歐洲/巴黎),您可能會感到困惑。不執(zhí)行此類轉(zhuǎn)換。Local在 java.time 名稱中意味著:沒有時區(qū)或偏移量。有人認(rèn)為該詞的使用Local因?yàn)檫@個含義具有誤導(dǎo)性(從某種意義上說,它是歷史性的,因?yàn)樗菑?java.time 的先驅(qū) Joda-Time 接管的)。
那么解析 RFC 3339 字符串(表示嵌入偏移中的瞬間)并將其轉(zhuǎn)換為 LocalDateTime可能的區(qū)域調(diào)整對象的正確方法是什么?假設(shè)機(jī)器在 CE[S]T 時區(qū)運(yùn)行。
解析已經(jīng)可以正確地為您工作。您可能不需要轉(zhuǎn)換??梢灾苯颖容^。和的和方法在isBefore比較時會考慮不同的偏移量或時區(qū),并將為您提供所需的結(jié)果。如果您確實(shí)想轉(zhuǎn)換:isEqualisAfterOffsetDateTimeZonedDateTime
? ? String text = "2019-08-28T10:39:57+08:00";
? ? OffsetDateTime time = OffsetDateTime.parse(text);
? ? System.out.println("Hour of day is " + time.getHour());
? ? ZoneId myTimeZone = ZoneId.of("Europe/Paris");
? ? ZonedDateTime timeInFrance = time.atZoneSameInstant(myTimeZone);
? ? System.out.println("Hour of day in France is " + timeInFrance.getHour());
Hour of day is 10
Hour of day in France is 4
同樣,您可以轉(zhuǎn)換為LocalDateTime并保留 4 點(diǎn),但我不明白您為什么應(yīng)該這樣做。
關(guān)于我對代碼的簡化:您的 RFC 3339 字符串包含與 UTC (+02:00) 的偏移量,而不是時區(qū)(如歐洲/巴黎或歐洲/羅馬)。所以用ZonedDateTime它來解析就有點(diǎn)矯枉過正了;OffsetDateTime是一個更好的選擇。字符串格式符合 ISO 8601。java.time 類可以直接解析最常見的 ISO 8601 格式變體,無需任何顯式格式化程序,因此我們在這里不需要格式化程序。順便說一句,您分配給格式化程序的區(qū)域沒有任何區(qū)別,因?yàn)槭褂昧俗址械钠屏俊?/p>
添加回答
舉報