Reputation: 23015
According to the documentation for Instant, the minimum Instant is -1000000000-01-01T00:00Z
, so the year is -1000000000
and the timezone is UTC
. so I expected this program to work, and the atOffset
to be a noop:
import java.time.*;
public class A {
public static void main(String[] args) {
Instant i = Instant.MIN;
System.out.println(i);
System.out.println(i.atOffset(ZoneOffset.UTC));
}
}
But instead it throws this exception on the atOffset
:
-1000000000-01-01T00:00:00Z
Exception in thread "main" java.time.DateTimeException: Invalid value for Year (valid values -999999999 - 999999999): -1000000000
at java.time.temporal.ValueRange.checkValidIntValue(ValueRange.java:330)
at java.time.temporal.ChronoField.checkValidIntValue(ChronoField.java:722)
at java.time.LocalDate.ofEpochDay(LocalDate.java:341)
at java.time.LocalDateTime.ofEpochSecond(LocalDateTime.java:422)
at java.time.OffsetDateTime.ofInstant(OffsetDateTime.java:328)
at java.time.Instant.atOffset(Instant.java:1195)
at A.main(A.java:7)
Is that a bug? According to that validation's message the minimum year is -999999999
but the documentation says it is -1000000000
.
Upvotes: 0
Views: 3360
Reputation: 21975
This is not a bug, actually the action of invoking
i.atOffset(ZoneOffset.UTC)
triggers the creation of a OffsetDateTime
object which the javadoc clearly states the following
The minimum supported OffsetDateTime, '-999999999-01-01T00:00:00+18:00'.
So basically if you keep it an Instant
it's ok, but trying to change it may cause a problem
Upvotes: 2
Reputation: 5937
atOffset
returns an OffsetDateTime which has a different Min/Max.
The minimum supported OffsetDateTime, '-999999999-01-01T00:00:00+18:00'.
The maximum supported OffsetDateTime, '+999999999-12-31T23:59:59.999999999-18:00'.
The javadoc mentions that these min/max values are derived from LocalDateTime along with the max zone offsets, which appears to be why they don't match up to Instant.
The reason Instant has an extra year both ways, per documentation of Instant.
This is one year earlier than the minimum LocalDateTime. This provides sufficient values to handle the range of ZoneOffset which affect the instant in addition to the local date-time. The value is also chosen such that the value of the year fits in an int.
Covers the edge case where a LocalDateTime + Offset results in a time from the previous year.
The max practical value would be the minimum OffsetDateTime converted to an Instant, as everything prior to that date is a buffer for which there is no equivalent OffsetDateTime.
Upvotes: 5