gpt4 book ai didi

java - ZonedDateTime 和 Instant.toEpochMilli 的 MIN/MAX 值是多少?

转载 作者:搜寻专家 更新时间:2023-10-30 21:07:26 26 4
gpt4 key购买 nike

我想使用可以在 ZonedDateTimeInstant.toEpochMilli() 之间转换的 MIN/MAX 时间值,用作过滤器/查询的标记值。

我试过:

OffsetDateTime.MIN.toInstant().toEpochMilli();
OffsetDateTime.MAX.toInstant().toEpochMilli();

但我得到了这个异常(exception):

java.lang.ArithmeticException: long overflow

at java.lang.Math.multiplyExact(Math.java:892)
at java.time.Instant.toEpochMilli(Instant.java:1237)

然后我尝试了这个:

ZonedDateTime.ofInstant(Instant.MIN, ZoneId.systemDefault());
ZonedDateTime.ofInstant(Instant.MAX, ZoneId.systemDefault());

但后来我得到了这个异常:

java.time.DateTimeException: Invalid value for Year (valid values -999999999 - 999999999): -1000000001

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.ZonedDateTime.create(ZonedDateTime.java:456)
at java.time.ZonedDateTime.ofInstant(ZonedDateTime.java:409)

我也试过 'Z' ZoneId:

ZonedDateTime.ofInstant(Instant.MIN, ZoneId.of("Z"))

但这会返回与上一个相同的异常。

最后我尝试了以下方法,它似乎有效:

ZonedDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Z"));
ZonedDateTime.ofInstant(Instant.EPOCH.plusMillis(Long.MAX_VALUE), ZoneId.of("Z"));

这是最好的解决方案吗?

最佳答案

Instant.EPOCH 等同于 1970-01-01T00:00Z,所以我不确定它是否是一个很好的最小值候选者(它取决于当然,您的需求——如果您所有的约会都在 1970 年之后,那也没问题。

Instant.MINInstant.MAX 转换为 ZonedDateTime 并不总是有效,因为根据偏移量,字段可以设置为超出边界的值(就像在你的情况下发生的年份)。

如果您想要可以转换为 ZonedDateTimeInstant 的遥远日期,则不需要使用内置的 MIN/MAX 常量,因为它们使用非常远的日期(从 -1000000000 到 1000000000 这样的年份),这样远的日期的等效 epoch milli 值远大于(或小于)long 值(value)。

由于您需要使用 toEpochMilli() 并且它返回一个 long,因此您必须保持在 long 值的限制范围内:

Instant minInstant = Instant.ofEpochMilli(Long.MIN_VALUE);
Instant maxInstant = Instant.ofEpochMilli(Long.MAX_VALUE);
ZonedDateTime minZonedDateTime = minInstant.atZone(ZoneOffset.UTC);
ZonedDateTime maxZonedDateTime = maxInstant.atZone(ZoneOffset.UTC);

各自的值是:

minInstant=-292275055-05-16T16:47:04.192Z
maxInstant=+292278994-08-17T07:12:55.807Z
minZonedDateTime=-292275055-05-16T16:47:04.192Z
maxZonedDateTime=+292278994-08-17T07:12:55.807Z

以及 epoch milli 的相应值:

System.out.println("minInstant millis=" + minInstant.toEpochMilli());
System.out.println("maxInstant millis=" + maxInstant.toEpochMilli());

minInstant millis=-9223372036854775808
maxInstant millis=9223372036854775807

我使用 ZoneOffset.UTC 而不是某个特定时区,因为这些日期是过去/ future 的日期,几个小时的偏移量不会有太大区别。无论如何,它们都相当于同一个毫秒。

您还可以使用 atOffset 方法(例如 minInstant.atOffset(ZoneOffset.UTC))。


注意事项:

  • 您可以使用常量 ZoneOffset.UTC 而不是 ZoneId.of("Z")。实际上,如果您检查 ZoneId.of("Z").equals(ZoneOffset.UTC),结果为 true
    甚至 ZoneId.of("Z") == ZoneOffset.UTC 也是 true,所以两者实际上是一回事。
  • 根据您的查询值,您不需要使用这么远的日期。例如,您可以将最小值设置为 1900 年,将最大值设置为 2900 年。这完全取决于您的数据集。但是,如果您的数据库可以处理一年中如此大的值,那么使用上述方法就可以了。

关于java - ZonedDateTime 和 Instant.toEpochMilli 的 MIN/MAX 值是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45043236/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com