为什么从 LocalDateTime 到 Instant 的转换不起作用?

Why is conversion from LocalDateTime to Instant not working?

提问人:APTower 提问时间:10/26/2022 最后编辑:AnonymousAPTower 更新时间:11/2/2022 访问量:219

问:

你知道为什么吗 4.和 6.打印在以下代码中有错误的时间?

LocalDateTime ldtNow = LocalDateTime.now();
LocalDateTime ldtNextMonth = ldtNow.plusMonths(1);

System.out.println("1. " + ldtNow);
System.out.println("2. " + ldtNextMonth);

System.out.println("3. " + ldtNow.atZone(ZoneId.systemDefault()).toInstant().toString());
System.out.println("4. " + ldtNextMonth.atZone(ZoneId.systemDefault()).toInstant().toString());

System.out.println("5. " + ldtNow.atZone(ZoneOffset.systemDefault()).toInstant().toString());
System.out.println("6. " + ldtNextMonth.atZone(ZoneOffset.systemDefault()).toInstant().toString());

这是它打印的内容:

 1. 2022-10-26T16:53:59.691891
 2. 2022-11-26T16:53:59.691891

 3. 2022-10-26T14:53:59.691891Z
 4. 2022-11-26T15:53:59.691891Z //WRONG?

 5. 2022-10-26T14:53:59.691891Z
 6. 2022-11-26T15:53:59.691891Z //WRONG?

打印 3.& 4.使用 ZoneId 进行测试并打印 5。& 6.替换为 ZoneOffset。

3.& 4.(和 5. 和 6.)是 LocalDateTime#plusMonths 方法的用法。我应该怎么做才能在零时间获得正确的结果 (2022-11-26T14:53:59.691891Z)?

java java-time localdatetime java.time.instant

评论

3赞 deHaar 10/26/2022
您似乎意外地涉及 DST 更改。您系统的默认时区是什么?它可能会在 10 月底发生变化并增加一个小时!取而代之 ...ZoneId.of("UTC")ZoneId.systemDefault()
0赞 devin 10/26/2022
如果他们在 10 月 @deHaar 日之后增加一个小时,第二个不也是一个小时加 16 吗
0赞 deHaar 10/26/2022
这就是OP必须找出的......我不确定是否是这样,但这是可能的......这意味着试试看。
1赞 APTower 10/26/2022
我的系统默认值是欧洲/布拉格。没想到10月底会是时间变化。你是对的!使用时,它会产生相同的结果。ZoneId.of("UTC")
1赞 user16320675 10/26/2022
@devin NO,没有时区的概念(也是需要转换它的原因)LocalDateTimeatZone()

答:

1赞 c3R1cGFy 10/27/2022 #1

该方法返回 ZonedDatetime,然后体验夏令时效果。 全球不同地区在不同的日期实行夏令时。atZone()

所以你的印刷品是:

 1. 2022-10-26T16:53:59.691891  // LocalDateTime
 2. 2022-11-26T16:53:59.691891  // LocalDateTime

 3. 2022-10-26T14:53:59.691891Z // ZonedDateTime
 4. 2022-11-26T15:53:59.691891Z // ZonedDateTime

 5. 2022-10-26T14:53:59.691891Z // ZonedDateTime
 6. 2022-11-26T15:53:59.691891Z // ZonedDateTime  

UTC时区类似于任何其他时区的参考点。例如,时区具有 和 取决于一年中的时间段的区域偏移量。CET, central european timeUTC+2UTC+1

您可以通过执行以下代码片段来查看此效果:

ZonedDateTime zdt1 = ldtNow.atZone(ZoneOffset.systemDefault());
ZonedDateTime zdt2 = ldtNextMonth.atZone(ZoneOffset.systemDefault());

System.out.println(ZoneOffset.from(zdt1));   // prints +02:00
System.out.println(ZoneOffset.from(zdt2));   // prints +01:00

评论

1赞 Anonymous 10/28/2022
更准确地说,中欧时间在几个欧洲和北非时区使用,其中大多数(不是全部)使用夏令时 (DST)。有些人全年都停留在 UTC+1 上。否则是一个正确的答案。