<i18n dev> RFR: 8364752: Class java.time.Instant cannot parse all ISO 8601 date formats [v5]

Roger Riggs rriggs at openjdk.org
Mon Aug 18 18:16:17 UTC 2025


On Fri, 15 Aug 2025 16:52:01 GMT, Naoto Sato <naoto at openjdk.org> wrote:

>> `Instant.parse()` is expected to use the offset zone pattern `+HH:mm:ss` (as defined by `DateTimeFormatterBuilder.appendOffsetId()`), but it fails to parse hour-only offsets such as `+02`. This is because the actual implementation uses `+HH:MM:ss` as the pattern. While replacing the pattern in the implementation as with the specification would allow hour-only offsets, it would also introduce compatibility issues, i.e., printing would omit the minutes field when it is zero. So, it is preferable to update the specification to match the implementation. A CSR has also been drafted for this change.
>
> Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:
> 
>   copyright year update

src/java.base/share/classes/java/time/format/DateTimeFormatter.java line 1205:

> 1203:      * {@link DateTimeFormatterBuilder#appendOffset(String, String)
> 1204:      * appendOffset("+HH", "Z")} in lenient mode will be used to parse the offset,
> 1205:      * converting the instant to UTC as necessary.

Suggestion:

     * When parsing, the lenient mode behavior of
     * {@link DateTimeFormatterBuilder#appendOffset(String, String)
     * appendOffset("+HH", "Z")} will be used to parse the offset,
     * converting the instant to UTC as necessary.

The phrase "in lenient mode" after the mention of appendOffset made me think the caller had to set lenient mode.
Here and below in DateTimeFormatterBiulder.java.

src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java line 3893:

> 3891:                     .appendFraction(NANO_OF_SECOND, minDigits, maxDigits, true)
> 3892:                     .parseLenient()
> 3893:                     .appendOffset("+HH", "Z")

The "+HH" pattern is supposed to be ignoring minutes and seconds but it does not appear to.  In jshell, I see:

jshell> Instant.parse("2017-01-01T00:00:00.000-02:10:12")
$8 ==> 2017-01-01T02:10:12Z

It would be more consistent with the original pattern to use `"+HH:mm:ss"`

test/jdk/java/time/test/java/time/TestInstant.java line 170:

> 168:     @Test(dataProvider = "valid_instants")
> 169:     public void test_parse_valid(String instant) {
> 170:         Instant.parse(instant);

The test should verify the correct time is parsed.
And include cases where the minute and second are non-zero.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/26708#discussion_r2283043042
PR Review Comment: https://git.openjdk.org/jdk/pull/26708#discussion_r2283113795
PR Review Comment: https://git.openjdk.org/jdk/pull/26708#discussion_r2283096548


More information about the i18n-dev mailing list