java.time.Instant - error while parsing a huge date

216 Views Asked by At

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 :)?

1

There are 1 best solutions below

1
user16320675 On BEST ANSWER

Feature, not a bug

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