Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8365182

java.time.Instant should be able to parse ISO 8601 offsets of the form HH:mm:ss

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 26
    • core-libs
    • None
    • behavioral
    • low
    • All possible ISO 8601 offsets are now accepted, instead of throwing a DateTimeParseException.
    • Java API
    • SE

      Summary

      java.time.Instant should be able to parse ISO 8601 offsets of the form HH:mm:ss

      Problem

      The spec of DateTimeFormatterBuilder.appendOffsetId() it reads:

      This is equivalent to calling appendOffset("+HH:mm:ss", "Z")

      and in appendOffset(String, String):

      +HH:mm:ss - hour, with minute if non-zero or with minute and second if non-zero, with colon

      This implies the minutes are optional, so hour-only offsets such as "+02" should be parsed correctly. However, the actual behavior is not, because the actual implementation uses "+HH:MM:ss" for parsing/formatting the zone offset.

      Solution

      The proposed solution consists of two parts:

      • Correct the documentation of appendOffsetId(): Replace the pattern in the spec "+HH:mm:ss" with "+HH:MM:ss" to align with the implementation.
      • Allow ISO_INSTANT formatter to parse ISO 8601 offsets, by explicitly specifying the offset pattern "+HH" in appendOffset(), instead of appendOffsetId(). This enables parsing both ‘+HH:mm:ss’ and ‘+HHmmss’, covering all valid ISO 8601 offset formats

      Specification

      Replace the pattern in DateTimeFormatterBuilder.appendOffsetId() as follows:

            * Appends the zone offset, such as '+01:00', to the formatter.
            * <p>
            * This appends an instruction to format/parse the offset ID to the builder.
      -     * This is equivalent to calling {@code appendOffset("+HH:mm:ss", "Z")}.
      +     * This is equivalent to calling {@code appendOffset("+HH:MM:ss", "Z")}.
            * See {@link #appendOffset(String, String)} for details on formatting
            * and parsing.
            *

      Insert the following sentence in DateTimeFormatter.ISO_INSTANT:

      --- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java
      +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java
      @@ -1199,8 +1199,9 @@
            * When formatting, the instant will always be suffixed by 'Z' to indicate UTC.
            * The second-of-minute is always output.
            * The nano-of-second outputs zero, three, six or nine digits as necessary.
      -     * When parsing, the behaviour of {@link DateTimeFormatterBuilder#appendOffsetId()}
      -     * will be used to parse the offset, converting the instant to UTC as necessary.
      +     * When parsing, the lenient mode behaviour of
      +     * {@link DateTimeFormatterBuilder#appendOffset(String, String)
      +     * appendOffset("+HH", "Z")} in will be used to parse the offset,
      +     * converting the instant to UTC as necessary.
            * The time to at least the seconds field is required.
            * Fractional seconds from zero to nine are parsed.
            * The localized decimal style is not used.

      and in DateTimeFormatterBuilder.appendInstant():

      --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java
      +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java
      @@ -894,8 +894,9 @@ 
            * {@link DateTimeFormatter#parsedLeapSecond()} for full details.
            * <p>
            * When formatting, the instant will always be suffixed by 'Z' to indicate UTC.
      -     * When parsing, the behaviour of {@link DateTimeFormatterBuilder#appendOffsetId()}
      -     * will be used to parse the offset, converting the instant to UTC as necessary.
      +     * When parsing, the lenient mode behaviour of
      +     * {@link DateTimeFormatterBuilder#appendOffset(String, String)
      +     * appendOffset("+HH", "Z")} in will be used to parse the offset,
      +     * converting the instant to UTC as necessary.
            * <p>
            * An alternative to this method is to format/parse the instant as a single
            * epoch-seconds value. That is achieved using {@code appendValue(INSTANT_SECONDS)}.

            naoto Naoto Sato
            webbuggrp Webbug Group
            Roger Riggs
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: