[英]Convert String to LocalDateTime in Java
我有這個字符串
2020 年 8 月 7 日星期五 18:00:00 +0000
我需要將其轉換為 LocalDateTime
我嘗試了幾種方法:
創建一個 DateTimeFormatter 並解析字符串
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss", Locale.getDefault());
LocalDateTime parsedDate = LocalDateTime.parse(publishedString, formatter);
使用 SimpleDateFormat 將其轉換為 Date,然后將 resultDate 轉換為 LocalDateTime
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
SimpleDateFormat dateFormatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z");
Date date = dateFormatter.parse(publishedString);
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
兩種解決方案都給了我同樣的例外:
java.time.format.DateTimeParseException: Text 'Fri, 07 Aug 2020 18:00:00 +0000' could not be parsed
at index 0 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
如何轉換該字符串?
OffsetDateTime.parse(
"Fri, 07 Aug 2020 18:00:00 +0000" ,
DateTimeFormatter.RFC_1123_DATE_TIME
)
LocalDateTime
是錯誤的 class 您的輸入字符串包含+0000
,表示與 UTC 的偏移量。
所以你不應該使用LocalDateTime
。 class 故意缺少任何時區或偏移量的概念。 使用LocalDateTime
,您的字符串Fri, 07 Aug 2020 18:00:00 +0000
將在 2020 年 8 月 7 日變為 6M,但我們不知道那是日本東京的下午 6 點,法國圖盧茲的下午 6 點,還是法國的下午 6 點美國俄亥俄州托萊多——所有不同的時刻相隔幾個小時。
OffsetDateTime
相反,這個值應該被解析為OffsetDateTime
。
您輸入的格式是RFC 1123的格式。 該特定格式在java.time中預定義。
String input = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME;
OffsetDateTime odt = OffsetDateTime.parse( input , f );
odt.toString(): 2020-08-07T18:00Z
我了解您需要 API 的LocalDateTime
,由於您無法控制的設計問題,您正在嘗試在某個時間點使用LocalDateTime
。
如果外部合同規定要理解LocalDateTime
的時區或 UTC 偏移量,則可以使LocalDateTime
工作,至少在 99.977 % 的情況下。 在某些同事程序員不閱讀合同的那一天,您仍然會等待發生編程錯誤,這是我們無法在代碼中解決的問題,只能嘗試通過良好的注釋來緩解。
例如,如果合約顯示 UTC,那么我們需要確保將時間轉換為 UTC。 為此,我們需要字符串的偏移量。
ZoneOffset contractualOffset = ZoneOffset.UTC;
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.withOffsetSameInstant(contractualOffset)
.toLocalDateTime();
System.out.println(convertedDateTime);
Output:
2020-08-07T18:00
如果要求字符串中的偏移量已經為 0,則需要驗證它是否為 0,否則錯誤會被 go 忽略,用戶會得到錯誤的結果。 例如:
OffsetDateTime parsedOdt = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME);
if (! parsedOdt.getOffset().equals(contractualOffset)) {
throw new IllegalStateException("Offset must be " + contractualOffset
+ ", was " + parsedOdt.getOffset());
}
LocalDateTime convertedDateTime = parsedOdt.toLocalDateTime();
如果合同提到某個時區,則轉換為該時區。 我以澳大利亞/維多利亞為例。
ZoneId contractualZone = ZoneId.of("Australia/Victoria");
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.atZoneSameInstant(contractualZone)
.toLocalDateTime();
System.out.println(convertedDateTime);
2020-08-08T04:00
在時鍾倒轉的時間異常情況下,您將得到一個模棱兩可的結果,例如在夏令時 (DST) 結束時的倒退。
此處解釋了您的異常的原因:
我會說使用 Locale.ROOT 並且不要忘記 DateTimeFormatter class 中的 Z
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss Z", Locale.ROOT);
LocalDateTime parsedDate = LocalDateTime.parse(dateString, formatter);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.