Java 8 DateTimeFormatter: confusion with 'z' and 'Z ' pattern letters

NinjaMester picture NinjaMester · Mar 31, 2016 · Viewed 8.7k times · Source

I have the date string "2015-01-12T13:00:00.000+02:00". Looking at the JavaDoc I see the following:

z       time-zone name              zone-name         Pacific Standard Time; PST
Z       zone-offset                 offset-Z          +0000; -0800; -08:00;


So I would suspect that to parse it I would have to use upper-case 'Z' because I have the Zone format given in +02:00:

DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.000Z");

But with that I get a parse error.

If I use lower-case 'z' it works:

DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.000z")


Does anyone know what is going on?


CODE:

DateTimeFormatter changetimeParser_Z = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.000Z");
DateTimeFormatter changetimeParser_z = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.000z");

String time = "2015-01-12T13:00:00.000+02:00";

ZonedDateTime time1 = ZonedDateTime.parse(time, changetimeParser_z);
System.out.println(time1);
ZonedDateTime time2 = ZonedDateTime.parse(time, changetimeParser_Z);

System.out.println(time2);


Exception stack trace:

2015-01-12T13:00+02:00
java.time.format.DateTimeParseException: Text '2015-01-12T13:00:00.000+02:00' could not be parsed at index 23
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)

Answer

SubOptimal picture SubOptimal · Mar 31, 2016

I would believe it's an error in the Javadoc and this part is a mistake

Symbol  Meaning                     Presentation      Examples<br>
------  -------                     ------------      -------
Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

because if you read further you find the explanation of the offset Z

Offset Z: This formats the offset based on the number of pattern letters. One, two or three letters outputs the hour and minute, without a colon, such as '+0130'. The output will be '+0000' when the offset is zero. Four letters outputs the full form of localized offset, equivalent to four letters of Offset-O. The output will be the corresponding localized offset text if the offset is zero. Five letters outputs the hour, minute, with optional second if non-zero, with colon. It outputs 'Z' if the offset is zero. Six or more letters throws IllegalArgumentException.

Which complies RFC 822.

For me the pattern should behave same as for SimpleDateFormat