jac*_*cob 13 java java-8 java-time
我想使用可以在ZonedDateTime和之间进行转换的MIN/MAX时间值Instant.toEpochMilli(),以用作过滤器/查询的标记值.
我试过了:
OffsetDateTime.MIN.toInstant().toEpochMilli();
OffsetDateTime.MAX.toInstant().toEpochMilli();
Run Code Online (Sandbox Code Playgroud)
但我得到这个例外:
java.lang.ArithmeticException: long overflow
at java.lang.Math.multiplyExact(Math.java:892)
at java.time.Instant.toEpochMilli(Instant.java:1237)
Run Code Online (Sandbox Code Playgroud)
然后我尝试了这个:
ZonedDateTime.ofInstant(Instant.MIN, ZoneId.systemDefault());
ZonedDateTime.ofInstant(Instant.MAX, ZoneId.systemDefault());
Run Code Online (Sandbox Code Playgroud)
但后来我得到了这个例外:
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)
Run Code Online (Sandbox Code Playgroud)
我也试过'Z' ZoneId:
ZonedDateTime.ofInstant(Instant.MIN, ZoneId.of("Z"))
Run Code Online (Sandbox Code Playgroud)
但是返回与最后一个相同的异常.
最后我尝试了以下,它似乎工作:
ZonedDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Z"));
ZonedDateTime.ofInstant(Instant.EPOCH.plusMillis(Long.MAX_VALUE), ZoneId.of("Z"));
Run Code Online (Sandbox Code Playgroud)
这是最好的解决方案吗?
小智 13
Instant.EPOCH相当于1970-01-01T00:00Z,所以我不确定它是否是最小值的好候选者(当然,这取决于你的需求 - 如果所有日期都在1970年以后,那就没关系了).
转换Instant.MIN和Instant.MAX对ZonedDateTime不起作用,因为根据偏移,字段可以设置为值超出界限(如发生与年,你的情况)的所有时光.
如果你想遥远的日期可以转换为ZonedDateTime和Instant,你并不需要使用内置的MIN/MAX常数,因为它们使用很远的日期(从几年如-1000000000到1000000000),和等效时代毫这些远日期的值远远大于(或低于)long值的限制.
当您需要使用toEpochMilli()它并返回a时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);
Run Code Online (Sandbox Code Playgroud)
各自的值是:
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());
Run Code Online (Sandbox Code Playgroud)
minInstant millis = -9223372036854775808
maxInstant millis = 9223372036854775807
我使用的ZoneOffset.UTC不是某个特定的时区,因为这些日期是过去/未来的迄今为止,几个小时的偏移量不会产生太大的影响.无论如何,它们都将相同于毫秒.
您还可以将转换Instant为OffsetDateTime使用atOffset方法(例如minInstant.atOffset(ZoneOffset.UTC)).
备注:
ZoneId.of("Z"),你可以使用常量ZoneOffset.UTC.实际上,如果你检查ZoneId.of("Z").equals(ZoneOffset.UTC),结果是true.ZoneId.of("Z") == ZoneOffset.UTC也是true,所以两者都是一回事.| 归档时间: |
|
| 查看次数: |
4492 次 |
| 最近记录: |