JDK-8210336 : DateTimeFormatter predefined formatters should support short time zone offsets
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.time
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2018-09-03
  • Updated: 2018-09-04
Related Reports
Relates :  
Description
The bug fix for 
JDK-8032051
"ZonedDateTime" class "parse" method fails with short time zone offset ("+01")
fixed DateTimeFormatter.ISO_ZONED_DATE_TIME, but it seems like other DateTimeFormatter predefined formatters have the same problem, and need a similar fix.  That is, any formatter that accepts an offset "+01:00" should also accept "+01" unless there's an industry spec to the contrary.

(as reported by a colleague)

import java.time.format.DateTimeFormatter;
import static java.time.format.DateTimeFormatter.ISO_DATE;
import static java.time.format.DateTimeFormatter.ISO_DATE_TIME;
import static java.time.format.DateTimeFormatter.ISO_OFFSET_DATE;
import static java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME;
import static java.time.format.DateTimeFormatter.ISO_OFFSET_TIME;
import static java.time.format.DateTimeFormatter.ISO_TIME;
import static java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME;

public class DateTimeParse {
    static void test(DateTimeFormatter formatter, String x) {
        try {
            formatter.parse(x);
        } catch (Throwable t) { t.printStackTrace(); }
    }

    public static void main(String[] args) throws Throwable {
        // no exceptions
        test(ISO_ZONED_DATE_TIME, "2013-12-11T21:25:04.800842+01:00");
        test(ISO_ZONED_DATE_TIME, "2013-12-11T21:25:04.800842+01");
        test(ISO_OFFSET_DATE_TIME, "2013-12-11T21:25:04.800842+01:00");
        test(ISO_OFFSET_DATE_TIME, "2013-12-11T21:25:04.800842+01");

        // exceptions ...
        test(ISO_DATE_TIME, "2013-12-11T21:25:04.800842+01:00");
        test(ISO_DATE_TIME, "2013-12-11T21:25:04.800842+01");
        test(ISO_OFFSET_DATE, "2013-12-11+01:00");
        test(ISO_OFFSET_DATE, "2013-12-11+01");
        test(ISO_DATE, "2013-12-11+01:00");
        test(ISO_DATE, "2013-12-11+01");
        test(ISO_OFFSET_TIME, "21:25:04.800842+01:00");
        test(ISO_OFFSET_TIME, "21:25:04.800842+01");
        test(ISO_TIME, "21:25:04.800842+01:00");
        test(ISO_TIME, "21:25:04.800842+01");
    }
}


=>

java.time.format.DateTimeParseException: Text '2013-12-11T21:25:04.800842+01' could not be parsed, unparsed text found at index 26
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874)
	at DateTimeParse.test(DateTimeParse.java:13)
	at DateTimeParse.main(DateTimeParse.java:26)
java.time.format.DateTimeParseException: Text '2013-12-11+01' could not be parsed at index 10
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874)
	at DateTimeParse.test(DateTimeParse.java:13)
	at DateTimeParse.main(DateTimeParse.java:28)
java.time.format.DateTimeParseException: Text '2013-12-11+01' could not be parsed, unparsed text found at index 10
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874)
	at DateTimeParse.test(DateTimeParse.java:13)
	at DateTimeParse.main(DateTimeParse.java:30)
java.time.format.DateTimeParseException: Text '21:25:04.800842+01' could not be parsed at index 15
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874)
	at DateTimeParse.test(DateTimeParse.java:13)
	at DateTimeParse.main(DateTimeParse.java:32)
java.time.format.DateTimeParseException: Text '21:25:04.800842+01' could not be parsed, unparsed text found at index 15
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874)
	at DateTimeParse.test(DateTimeParse.java:13)
	at DateTimeParse.main(DateTimeParse.java:34)

Comments
The obvious way to try to fix this is to apply the same wrapping of parseLenient and parseStrict that was used to fix ISO_OFFSET_DATE_TIME to the other formatters. ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder() .parseCaseInsensitive() .append(ISO_LOCAL_DATE_TIME) + .parseLenient() .appendOffsetId() + .parseStrict() .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
04-09-2018