解析日期时无法从TemporalAccessor获取ZonedDateTime [英] Unable to obtain ZonedDateTime from TemporalAccessor when parsing a Date

查看:9994
本文介绍了解析日期时无法从TemporalAccessor获取ZonedDateTime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Java 1.8.0_51以下代码(取自无法从TemporalAccessor获取OffsetDateTime日期时间格式化(DateTimeFormatter.ofPattern)(yyyyMMdd)withZone(ZoneId.of(Europe /柏林));
OffsetDateTime offsetDateTime = ZonedDateTime.parse(20151113,格式化程序).toOffsetDateTime();
System.out.println(offsetDateTime.format(DateTimeFormatter.ISO_DATE));

抛出异常:

  java.time.format.DateTimeParseException:无法解析文本'20151113':无法从TemporalAccessor获取ZonedDateTime:{},ISO,Europe / Berlin解析为类型为java的2015-11-13。 time.format.Parsed 
在java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
在java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
在java.time.ZonedDateTime.parse(ZonedDateTime.java:597)

我做错了什么这一次?

你忘了设定一个时间。



如果您将我的答案与您的代码进行比较,您可以注意到唯一的区别是时间信息丢失。一个 ZonedDateTime 包含时间信息,由于您当前的格式化程序不处理它,因此 ZonedDateTime 的实例不能形成。



您还可以在堆栈跟踪中看到它,其中包含

 导致:java.time.DateTimeException:无法从TemporalAccessor获取LocalTime:{},ISO,Europe / Berlin解析为2015-11-13类型为java.time.format.Parsed 
在java.time.LocalTime.from(LocalTime.java:409)
在java.time.ZonedDateTime.from(ZonedDateTime.java:560)
... 5更多

根据您想要的内容,您可以使用 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,格式化程序).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,格式化程序);
ZonedDateTime zonedDateTime = ZonedDateTime.of(解析,LocalTime.MIDNIGHT,ZoneId.of(Europe / Berlin));
// get OffsetDateTime同样
}


With Java 1.8.0_51 the following code (taken from Unable to obtain OffsetDateTime from TemporalAccessor)

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));

throws an 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)

What am I doing wrong this time?

解决方案

You are forgetting to set a time.

If you compare my answer with your code, you can notice that the only difference is that the time information missing. A ZonedDateTime contains a time information and since your current formatter does not handle it, an instance of ZonedDateTime can't be formed.

You can also see it in the stacktrace, that contains

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

Depending on what you want, you could build a custom formatter with 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 to 0. A sample example would be

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));
}


Another possible solution would be to parse the text as a LocalDate and then construct a ZoneDateTime with it:

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
}

这篇关于解析日期时无法从TemporalAccessor获取ZonedDateTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆