The ISO_INSTANT formatter is documented here – “This is a special case formatter intended to allow a human readable form of an Instant”. As such, this formatter is intended for use with an Instant not a ZonedDateTime.
Formatting
When formatting, ISO_INSTANT can format any temporal object that can provide ChronoField.INSTANT_SECONDS and ChronoField.NANO_OF_SECOND. Both Instant and ZonedDateTime can provide these two fields, thus 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
When parsing, ISO_INSTANT will only produce ChronoField.INSTANT_SECONDS and ChronoField.NANO_OF_SECOND. An Instant can be built from those two fields, but ZonedDateTime requires a ZoneId as well:
To parse a ZonedDateTime it is essential that a time-zone ZoneId is present. 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 documentation for ISO_ZONED_DATE_TIME, ISO_OFFSET_DATE_TIME and ISO_DATE_TIME (any of these three can be used to parse a ZonedDateTime without specifying withZone()).
Summary
The ISO_INSTANT formatter 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.