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

问题描述 投票:0回答:2

根据documentation for 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

java java-time
2个回答
5
投票

atOffset返回一个具有不同Min / Max的OffsetDateTime

支持的最小OffsetDateTime,' - 999999999-01-01T00:00:00 + 18:00'。

支持的最大OffsetDateTime,'+ 999999999-12-31T23:59:59.999999999-18:00'。

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

根据Instant的文档,Instant有两个额外年份的原因。

这比最小的LocalDateTime提前一年。这提供了足够的值来处理ZoneOffset的范围,除了本地日期时间之外,它还影响瞬间。还选择该值使得年份的值适合int。

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

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


2
投票

这不是一个bug,实际上是调用的动作

i.atOffset(ZoneOffset.UTC)

触发了OffsetDateTime对象的创建,javadoc清楚地说明了以下内容

支持的最小OffsetDateTime,' - 999999999-01-01T00:00:00 + 18:00'。

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

© www.soinside.com 2019 - 2024. All rights reserved.