Java Instant 的错误? `DateTimeException:年份值无效`

Java Instant's bug? `DateTimeException: Invalid value for Year`

根据 documentation for Instant,最小 Instant 为 -1000000000-01-01T00:00Z,因此年份为 -1000000000,时区为 UTC。所以我希望这个程序能够工作,并且 atOffset 是一个 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));
   }
}

而是在 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)

这是一个错误吗?根据该验证的消息,最小年份是 -999999999 但文档说它是 -1000000000.

atOffset returns 一个 OffsetDateTime 有不同的 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'.

javadoc 提到这些 min/max 值来自 LocalDateTime 以及最大区域偏移,这似乎是它们与 Instant 不匹配的原因。

根据 Instant.

的文档,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.

涵盖 LocalDateTime + Offset 导致上一年时间的边缘情况。

最大实际值将是转换为 Instant 的最小 OffsetDateTime,因为该日期之前的所有内容都是缓冲区,没有等效的 OffsetDateTime。

这不是bug,实际上是调用

的动作
i.atOffset(ZoneOffset.UTC)

触发 OffsetDateTime 对象的创建,javadoc 明确说明以下内容

The minimum supported OffsetDateTime, '-999999999-01-01T00:00:00+18:00'.

所以基本上如果你保持它 Instant 没问题,但尝试改变它可能会导致问题