I'm trying to parse a really large date (but still way less than Instant.MAX) using the Instant.parse method but getting an error.
String input = "78000000-01-01T00:00:00Z";
Instant instant = Instant.parse(input);
Exception:
Exception in thread "main" java.time.format.DateTimeParseException: Text '78000000-01-01T00:00:00Z' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2106)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2008)
at java.base/java.time.Instant.parse(Instant.java:399)
The BC date "-78000000-01-01T00:00:00Z" is parsed ok.
Did I find a bug in Java :)?
No, it is not a bug - is working as specified!
From documentation of parse()
:
is parsed using DateTimeFormatter.ISO_INSTANT
and from ISO_INSTANT
returns an immutable formatter capable of formatting and parsing the ISO-8601 instant format
ISO_INSTANT
refers to ISO_OFFSET_DATE_TIME
to ISO_LOCAL_DATE_TIME
to ISO_LOCAL_DATE
. The last one says:
- Four digits or more for the year. Years in the range 0000 to 9999
will be pre-padded by zero to ensure four digits. Years outside that
range will have a prefixed positive or negative symbol.
This is meant to imply that years to be parsed must abide by the mentioned format too.
Finally, from Wikipedia for ISO-8601 (Years):
To represent years before 0000 or after 9999, the standard also permits the expansion of the year representation .... An expanded year representation [±YYYYY] must have an agreed-upon number of extra year digits beyond the four-digit minimum, and it must be prefixed with a + or − sign.
Emphasis mine
The input string "78000000-01-01T00:00:00Z"
is missing that +
sign, while "-78000000-01-01T00:00:00Z"
correctly starts with a -
sign.
The input "+78000000-01-01T00:00:00Z"
is parsed without error.
Hint: you can check the format by formatting a test date/time/... before parsing.
For example:
var test = Instant.from(OffsetDateTime.of(78000000, 1, 1, 0, 0, 0, 0,ZoneOffset.UTC));
System.out.println(test.toString()); // or using any relevant formatter
Output:
+78000000-01-01T00:00:00Z