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" inappendOffset()
, instead ofappendOffsetId()
. 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)}.
- csr of
-
JDK-8364752 java.time.Instant should be able to parse ISO 8601 offsets of the form HH:mm:ss
-
- Resolved
-