解析日期时无法从TemporalAccessor获取ZonedDateTime
使用Java 1.8.0_51以下代码(取自Unable从TemporalAccessor获取OffsetDateTime )
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));
抛出exception:
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
构建自定义格式化程序,并调用parseDefaulting
为每个时间字段字段提供默认值。 如果您想默认为午夜,可以将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 }
Java 8 java.time.*
包是一个非常严格的包。 它不允许类型和输入之间的灵活性 – 如果您需要ZonedDateTime
对象,则必须从具有时区,日期和时间的输入构造它。
如果您只想使用日期来构造对象,则它必须是没有时间字段的类型,特别是LocalDate
。