解析日期时无法从 TemporalAccessor 获取 ZonedDateTime
Unable to obtain ZonedDateTime from TemporalAccessor when parsing a Date
用Java1.8.0_51下面的代码(摘自)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd").withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime offsetDateTime = ZonedDateTime.parse("20151113", formatter).toOffsetDateTime();
System.out.println(offsetDateTime.format(DateTimeFormatter.ISO_DATE));
抛出异常:
java.time.format.DateTimeParseException: Text '20151113' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO,Europe/Berlin resolved to 2015-11-13 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.ZonedDateTime.parse(ZonedDateTime.java:597)
这次我做错了什么?
您忘记设置时间了。
如果将 与您的代码进行比较,您会发现唯一的区别是缺少时间信息。 ZonedDateTime
包含时间信息,由于您当前的格式化程序不处理它,因此无法形成 ZonedDateTime
的实例。
您还可以在堆栈跟踪中看到它,其中包含
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {},ISO,Europe/Berlin resolved to 2015-11-13 of type java.time.format.Parsed
at java.time.LocalTime.from(LocalTime.java:409)
at java.time.ZonedDateTime.from(ZonedDateTime.java:560)
... 5 more
根据您的需要,您可以构建一个自定义格式化程序,其中 DateTimeFormatterBuilder
and call parseDefaulting
to provide a default values for each time chrono fields. If you want to default to midnight, you can set NANO_OF_DAY
为 0。示例为
public static void main(String[] args) {
DateTimeFormatter formatter =
new DateTimeFormatterBuilder().appendPattern("yyyyMMdd")
.parseDefaulting(ChronoField.NANO_OF_DAY, 0)
.toFormatter()
.withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime offsetDateTime = ZonedDateTime.parse("20151113", formatter).toOffsetDateTime();
System.out.println(offsetDateTime.format(DateTimeFormatter.ISO_DATE));
}
另一个可能的解决方案是将文本解析为 LocalDate
,然后用它构造一个 ZoneDateTime
:
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate parsed = LocalDate.parse("20151113", formatter);
ZonedDateTime zonedDateTime = ZonedDateTime.of(parsed, LocalTime.MIDNIGHT, ZoneId.of("Europe/Berlin"));
// get OffsetDateTime similarly
}
Java8 java.time.*
包是一个非常严格的包。它不允许类型和输入之间的灵活性 - 如果您想要一个 ZonedDateTime
对象,您必须从具有时区、日期和时间的输入构造它。
如果你想只是一个日期来构造一个对象,它必须是没有时间字段的类型,具体来说,LocalDate
.
用Java1.8.0_51下面的代码(摘自
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd").withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime offsetDateTime = ZonedDateTime.parse("20151113", formatter).toOffsetDateTime();
System.out.println(offsetDateTime.format(DateTimeFormatter.ISO_DATE));
抛出异常:
java.time.format.DateTimeParseException: Text '20151113' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO,Europe/Berlin resolved to 2015-11-13 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.ZonedDateTime.parse(ZonedDateTime.java:597)
这次我做错了什么?
您忘记设置时间了。
如果将 ZonedDateTime
包含时间信息,由于您当前的格式化程序不处理它,因此无法形成 ZonedDateTime
的实例。
您还可以在堆栈跟踪中看到它,其中包含
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {},ISO,Europe/Berlin resolved to 2015-11-13 of type java.time.format.Parsed
at java.time.LocalTime.from(LocalTime.java:409)
at java.time.ZonedDateTime.from(ZonedDateTime.java:560)
... 5 more
根据您的需要,您可以构建一个自定义格式化程序,其中 DateTimeFormatterBuilder
and call parseDefaulting
to provide a default values for each time chrono fields. If you want to default to midnight, you can set NANO_OF_DAY
为 0。示例为
public static void main(String[] args) {
DateTimeFormatter formatter =
new DateTimeFormatterBuilder().appendPattern("yyyyMMdd")
.parseDefaulting(ChronoField.NANO_OF_DAY, 0)
.toFormatter()
.withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime offsetDateTime = ZonedDateTime.parse("20151113", formatter).toOffsetDateTime();
System.out.println(offsetDateTime.format(DateTimeFormatter.ISO_DATE));
}
另一个可能的解决方案是将文本解析为 LocalDate
,然后用它构造一个 ZoneDateTime
:
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate parsed = LocalDate.parse("20151113", formatter);
ZonedDateTime zonedDateTime = ZonedDateTime.of(parsed, LocalTime.MIDNIGHT, ZoneId.of("Europe/Berlin"));
// get OffsetDateTime similarly
}
Java8 java.time.*
包是一个非常严格的包。它不允许类型和输入之间的灵活性 - 如果您想要一个 ZonedDateTime
对象,您必须从具有时区、日期和时间的输入构造它。
如果你想只是一个日期来构造一个对象,它必须是没有时间字段的类型,具体来说,LocalDate
.