[英]DateTimeParseException with LocalDateTime: Unable to obtain LocalDateTime from TemporalAccessor
[英]Unable to obtain LocalDateTime from TemporalAccessor when parsing LocalDateTime (Java 8)
我只是想在 Java 8 中將日期字符串轉換為 DateTime 對象。運行以下幾行:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime dt = LocalDateTime.parse("20140218", formatter);
我收到以下錯誤:
Exception in thread "main" java.time.format.DateTimeParseException:
Text '20140218' could not be parsed:
Unable to obtain LocalDateTime from TemporalAccessor:
{},ISO resolved to 2014-02-18 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
語法與這里建議的相同,但我遇到了一個例外。 我正在使用JDK-8u25
。
事實證明,Java 不接受裸 Date 值作為 DateTime。 使用 LocalDate 而不是 LocalDateTime 解決了這個問題:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);
如果您確實需要將日期轉換為 LocalDateTime 對象,則可以使用 LocalDate.atStartOfDay()。 這將為您提供指定日期的 LocalDateTime 對象,將小時、分鍾和秒字段設置為 0:
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();
如果有人應該再次閱讀這個主題(像我一樣),那么正確的答案將在DateTimeFormatter
定義中,例如:
private static DateTimeFormatter DATE_FORMAT =
new DateTimeFormatterBuilder().appendPattern("dd/MM/yyyy[ [HH][:mm][:ss][.SSS]]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
如果它們會出現,應該設置可選字段。 其余代碼應該完全相同。
編輯:來自wittyameta評論的有用的東西:
請記住在調用 appendPattern 之后添加 parseDefaulting。 否則它會給出 DateTimeParseException
對於遇到此錯誤的任何人,就像我一樣:
Unable to obtain LocalDateTime from TemporalAccessor: {HourOfAmPm=0, MinuteOfHour=0}
它來自以下行:
LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy h:mm"));
事實證明,這是因為我在 0 小時上使用了 12 小時模式,而不是 24 小時模式。
通過使用大寫 H 將小時模式更改為 24 小時模式來修復它:
LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy H:mm"));
這是一個非常不清楚且無用的錯誤消息。 經過多次反復試驗,我發現如果您不嘗試解析時間, LocalDateTime
會出現上述錯誤。 通過使用LocalDate
,它可以正常工作而不會出錯。
這沒有得到很好的記錄,相關的異常也非常無用。
擴展追溯的答案..:即使使用LocalDate
而不是LocalDateTime
我也遇到了同樣的問題。 問題是我使用.withResolverStyle(ResolverStyle.STRICT);
創建了我的DateTimeFormatter
。 ,所以我不得不使用日期模式uuuuMMdd
而不是yyyyMMdd
(即“年”而不是“時代”)!
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseStrict()
.appendPattern("uuuuMMdd")
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT);
LocalDate dt = LocalDate.parse("20140218", formatter);
(這個解決方案最初是對retrography答案的評論,但我被鼓勵將它作為一個獨立的答案發布,因為它顯然對很多人都非常有效。)
如果日期字符串不包含小時、分鍾等的任何值,則不能直接將其轉換為LocalDateTime
。 您只能將其轉換為LocalDate
,因為該字符串僅表示年、月和日期組件,這是正確的做法。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf); // 2018-03-06
無論如何,您可以將其轉換為LocalDateTime
。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf);
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00
DateTimeFormatter
您不需要定義DateTimeFormatter
來解析給定的日期字符串。 您可以使用 OOTB (Out-Of-The-Box)、 DateTimeFormatter.BASIC_ISO_DATE
來解析它。
演示:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("20140218", DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(date);
// In case you need an instance of LocalDateTime
LocalDateTime ldt = date.atTime(LocalTime.MIN);
System.out.println(ldt);
}
}
輸出:
2014-02-18
2014-02-18T00:00
從Trail: Date Time了解有關現代日期時間 API *的更多信息。
* 如果您正在為一個 Android 項目工作,並且您的 Android API 級別仍然不符合 Java-8,請 通過 desugaring 檢查可用的 Java 8+ API 。 請注意,Android 8.0 Oreo 已經提供了對java.time
的支持。 檢查此答案和此答案以了解如何將java.time
API 與 JDBC 一起使用。
這工作正常
public class DateDemo {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm");
String date = "16-08-2018 12:10";
LocalDate localDate = LocalDate.parse(date, formatter);
System.out.println("VALUE="+localDate);
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
LocalDateTime parse = LocalDateTime.parse(date, formatter1);
System.out.println("VALUE1="+parse);
}
}
輸出:
VALUE=2018-08-16
VALUE1=2018-08-16T12:10
DateTimeFormatter format = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.parseDefaulting(ChronoField.MILLI_OF_SECOND, 0)
.toFormatter();
為我工作
如果您只是想采用一種格式(無論它是否有時間)並想解析為 LocalDateTime,您可以執行以下操作。
LocalDateTime parseDateTime(String dateTime, DateTimeFormatter fmt) {
return fmt.parse(dateTime, t -> {
LocalDate date = t.query(TemporalQueries.localDate());
LocalTime time = t.query(TemporalQueries.localTime());
return LocalDateTime.of(date, time != null ? time : LocalTime.MIDNIGHT);
});
}
我需要這個,因為我將日期/時間模式作為自定義 Spark UDF 的參數。
試試這個:
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy");
LocalDate fromLocalDate = LocalDate.parse(fromdstrong textate, dateTimeFormatter);
您可以添加任何您想要的格式。 這對我行得通!
我遇到了這個問題,因為我的輸入字符串沒有年份:
輸入字符串: Tuesday, June 8 at 10:00 PM
formatter: DateTimeFormatter.ofPattern("EEEE, MMMM d 'at' h:mm a", Locale.US);
我知道年份,所以我只是將其附加到:
輸入字符串: Tuesday, June 8 at 6:30 PM 2021
formatter: DateTimeFormatter.ofPattern("EEEE, MMMM d 'at' h:mm a uuuu", Locale.US);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.