java – Java 8 – DateTimeFormatter and ISO_INSTANT problems with ZonedDateTime

The formatter ISO_INSTANT It is documented here – “This is a special case formatter intended to allow a human readable form of a Snapshot.” Therefore, this formatter is intended for use with a Instant not a ZonedDateTime.

Formatting

While formatting, ISO_INSTANT It can format any temporal object it can provide ChronoField.INSTANT_SECONDS And ChronoField.NANO_OF_SECOND. Both of them Instant And ZonedDateTime can provide these two fields, so they both work:

// works with Instant
Instant instant = Instant.now();
System.out.println(DateTimeFormatter.ISO_INSTANT.format(instant));

// works with ZonedDateTime 
ZonedDateTime zdt = ZonedDateTime.now();
System.out.println(zdt.format(DateTimeFormatter.ISO_INSTANT));

// example output
2014-09-02T08:05:23.653Z

Parsing

During the analysis, ISO_INSTANT It will only produce ChronoField.INSTANT_SECONDS And ChronoField.NANO_OF_SECOND. You can create a Instant from these two fields, but ZonedDateTime also requires a ZoneId:

To analyze a ZonedDateTime a time zone is essential ZoneId. The time zone can be (a) parsed from the string or (b) specified to the formatter (using JDK 8u20):

// option a - parsed from the string
DateTimeFormatter f = DateTimeFormatter.ISO_DATE_TIME;
ZonedDateTime zdt = ZonedDateTime.parse("2014-09-02T08:05:23.653Z", f);

// option b - specified in the formatter - REQUIRES JDK 8u20 !!!
DateTimeFormatter f = DateTimeFormatter.ISO_INSTANT.withZone(ZoneId.systemDefault());
ZonedDateTime zdt = ZonedDateTime.parse("2014-09-02T08:05:23.653Z", f);

See the documentation for ISO_ZONED_DATE_TIME , ISO_OFFSET_DATE_TIME And ISO_DATE_TIME (any of these three options be used to parse a ZonedDateTime without specifying withZone()).

Summary

The formatter ISO_INSTANT It is a special case formatter designed to work with Instant. If you are using a ZonedDateTime you should use a different formatter, such as ISO_DATE_TIME OR ISO_ZONED_DATE_TIME.

Leave a comment