Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

java - Unable to obtain ZonedDateTime from TemporalAccessor when parsing a Date

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...