mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-28 11:53:09 +00:00
8364752: java.time.Instant should be able to parse ISO 8601 offsets of the form HH:mm:ss
Reviewed-by: rriggs, vyazici, scolebourne
This commit is contained in:
parent
69645fd4ba
commit
1ff73cb2ec
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1199,8 +1199,10 @@ public final class DateTimeFormatter {
|
||||
* 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 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 time to at least the seconds field is required.
|
||||
* Fractional seconds from zero to nine are parsed.
|
||||
* The localized decimal style is not used.
|
||||
|
||||
@ -894,8 +894,10 @@ public final class DateTimeFormatterBuilder {
|
||||
* {@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")} 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)}.
|
||||
@ -956,7 +958,7 @@ public final class DateTimeFormatterBuilder {
|
||||
* 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.
|
||||
*
|
||||
@ -3887,7 +3889,8 @@ public final class DateTimeFormatterBuilder {
|
||||
.appendValue(MINUTE_OF_HOUR, 2).appendLiteral(':')
|
||||
.appendValue(SECOND_OF_MINUTE, 2)
|
||||
.appendFraction(NANO_OF_SECOND, minDigits, maxDigits, true)
|
||||
.appendOffsetId()
|
||||
.parseLenient()
|
||||
.appendOffset("+HH", "Z")
|
||||
.toFormatter().toPrinterParser(false);
|
||||
DateTimeParseContext newContext = context.copy();
|
||||
int pos = parser.parse(newContext, text, position);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -61,6 +61,9 @@ package test.java.time;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
@ -70,7 +73,7 @@ import static org.testng.Assert.assertThrows;
|
||||
|
||||
/**
|
||||
* Test Instant.
|
||||
* @bug 8273369 8331202
|
||||
* @bug 8273369 8331202 8364752
|
||||
*/
|
||||
@Test
|
||||
public class TestInstant extends AbstractTest {
|
||||
@ -151,4 +154,58 @@ public class TestInstant extends AbstractTest {
|
||||
Instant.now().until(null);
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
private Object[][] valid_instants() {
|
||||
var I1 = OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.of("+02")).toInstant();
|
||||
var I2 = OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.of("+02:02")).toInstant();
|
||||
var I3 = OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.of("+02:02:02")).toInstant();
|
||||
var I4 = OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.of("Z")).toInstant();
|
||||
return new Object[][] {
|
||||
{"2017-01-01T00:00:00.000+02", I1},
|
||||
{"2017-01-01T00:00:00.000+0200", I1},
|
||||
{"2017-01-01T00:00:00.000+02:00", I1},
|
||||
{"2017-01-01T00:00:00.000+020000", I1},
|
||||
{"2017-01-01T00:00:00.000+02:00:00", I1},
|
||||
|
||||
{"2017-01-01T00:00:00.000+0202", I2},
|
||||
{"2017-01-01T00:00:00.000+02:02", I2},
|
||||
|
||||
{"2017-01-01T00:00:00.000+020202", I3},
|
||||
{"2017-01-01T00:00:00.000+02:02:02", I3},
|
||||
|
||||
{"2017-01-01T00:00:00.000Z", I4},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "valid_instants")
|
||||
public void test_parse_valid(String instant, Instant expected) {
|
||||
assertEquals(Instant.parse(instant), expected);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
private Object[][] invalid_instants() {
|
||||
return new Object[][] {
|
||||
{"2017-01-01T00:00:00.000"},
|
||||
{"2017-01-01T00:00:00.000+0"},
|
||||
{"2017-01-01T00:00:00.000+0:"},
|
||||
{"2017-01-01T00:00:00.000+02:"},
|
||||
{"2017-01-01T00:00:00.000+020"},
|
||||
{"2017-01-01T00:00:00.000+02:0"},
|
||||
{"2017-01-01T00:00:00.000+02:0:"},
|
||||
{"2017-01-01T00:00:00.000+02:00:"},
|
||||
{"2017-01-01T00:00:00.000+02:000"},
|
||||
{"2017-01-01T00:00:00.000+02:00:0"},
|
||||
{"2017-01-01T00:00:00.000+02:00:0:"},
|
||||
{"2017-01-01T00:00:00.000+0200000"},
|
||||
{"2017-01-01T00:00:00.000+02:00:000"},
|
||||
{"2017-01-01T00:00:00.000+02:00:00:"},
|
||||
{"2017-01-01T00:00:00.000UTC"},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalid_instants")
|
||||
public void test_parse_invalid(String instant) {
|
||||
assertThrows(DateTimeParseException.class, () -> Instant.parse(instant));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user