Why does the following fail to run, with the date-time string unable to parse as an OffsetDateTime
?
String inputOdt = "2016-01-23T12:34:56 GMT+8";
DateTimeFormatter formatterOdt = DateTimeFormatter.ofPattern ( "yyyy-MM-dd'T'HH:mm:ss O" );
OffsetDateTime odt = OffsetDateTime.parse ( inputOdt , formatterOdt );
Using Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
on Mac OS X El Capitan 10.11.4.
Generates error:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2016-01-23T12:34:56 GMT+8' could not be parsed: String index out of range: 25
The offset-from-UTC string GMT+8
is copied-pasted from the example in the class documentation for DateTimeFormatter
. To quote:
Offset O: This formats the localized offset based on the number of pattern letters. One letter outputs the short form of the localized offset, which is localized offset text, such as 'GMT', with hour without leading zero, optional 2-digit minute and second if non-zero, and colon, for example 'GMT+8'.
The rest of the string parses successfully as a LocalDateTime
. So the problem seems to indeed be the offset-from-UTC part.
String inputLdt = "2016-01-23T12:34:56";
DateTimeFormatter formatterLdt = DateTimeFormatter.ofPattern ( "yyyy-MM-dd'T'HH:mm:ss" );
LocalDateTime ldt = LocalDateTime.parse ( inputLdt , formatterLdt );
System.out.println ( "" );
System.out.println ( "inputLdt: " + inputLdt );
System.out.println ( "ldt: " + ldt );
inputLdt: 2016-01-23T12:34:56
ldt: 2016-01-23T12:34:56
A partial workaround is to add a trailing SPACE to both the input string and the formatting pattern. So this works.
String input = "Sat May 02 2015 00:00:00 GMT+08 "; // Trailing space.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "EEE MMM dd yyyy HH:mm:ss O " ); // Trailing space.
OffsetDateTime odt = OffsetDateTime.parse ( input , formatter ); // SUCCEEDS
But adding minutes without a colon is documented as working with a single O
but it fails. This workaround of a trailing SPACE does not help in such a case. Notice the GMT+0800
in this example versus GMT+08
seen directly above, where this example fails but the one above succeeds.
String input = "Sat May 02 2015 00:00:00 GMT+0800 "; // Minutes in the offset, and trailing space.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "EEE MMM dd yyyy HH:mm:ss O " ); // Trailing space.
OffsetDateTime odt = OffsetDateTime.parse ( input , formatter ); // FAILS
Seems to be a bug in Java. See https://bugs.openjdk.java.net/browse/JDK-8154050:
java.time.format.DateTimeFormatter can't parse localized zone-offset
The DateTimeFormatter fails to parse its own output for format strings containing "O". The following code throws a StringIndexOutOfBoundsException on the final line.
import java.time.ZoneOffset import java.time.ZonedDateTime import java.time.format.DateTimeFormatter DateTimeFormatter formatter = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ss.S O") .withLocale(Locale.ENGLISH) String date = formatter.format(ZonedDateTime.now(ZoneOffset.UTC)); formatter.parse(date)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.time.format.DateTimeParseException: Text '2016-04-08T10:49:52.7 GMT' could not be parsed: String index out of range: 25
And in a comment:
Attached test case executed on:
JDK 8 - Fail
JDK 8u77 - Fail
JDK 9EA - Fail
Seems it was fixed in Java 9 build b116.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With