如何从 Instant 转换为 LocalDate

How to convert from Instant to LocalDate

我有一个 Instant 来自一个来源,根据规范,它应该是一个 LocalDate,但是在 LocalDate [=19] 中没有看到任何方法=] 将 Instant 转换为 LocalDate.

最好的方法是什么?

您需要问问自己最有可能将其转换到哪个区域偏移量,以及何时知道答案:

LocalDate.ofInstant(yourInstant, yourZoneOffSet)

编辑

刚刚意识到这只有在 java-9 之后才有可能,对于 java9 之前的版本,请参阅

Java9+

LocalDate.ofInstant(...) 到达 Java 9.

Instant instant = Instant.parse("2020-01-23T00:00:00Z");
ZoneId zone = ZoneId.of("America/Edmonton");
LocalDate date = LocalDate.ofInstant(instant, zone);

code run live at IdeOne.com

请注意 日期是 22 日而不是 23 日,因为该时区使用的偏移量比 UTC 早几个小时。

2020-01-22

Java 8

如果您正在使用 Java 8,那么您可以使用 ZonedDateTimetoLocalDate() 方法:

yourInstant.atZone(yourZoneId).toLocalDate()

其他答案提供了转换的机制,但我想补充一些关于这种转换含义的背景知识,希望这有助于解释为什么它以这种方式工作。


LocalDateInstant 看起来很相似——它们都包含没有时区信息的日期(/时间)信息。但是,它们的含义却大不相同。

Instant 明确表示一个时间点。该表示没有明确包含任何时区,但隐含地引用了 UTC 时间线。

LocalDateTime(和LocalDate)是有歧义的,因为它代表了local时间轴中的一个点,它隐含地引用了本地时区。

因此,为了将 Instant 正确地转换为 LocalDateTime(概念上——其中一些步骤在实现中捆绑在一起成为一个操作)您需要:
1. 通过应用 UTC 时区信息
Instant 转换为 ZonedDateTime 2. 将时区从 UTC 更改为 local 时区(这意味着应用相关时区偏移量),这会为您提供另一个 ZonedDateTime(具有不同时区)
3. 将 ZonedDateTime 转换为 LocalDateTime,通过删除时区信息使时区隐含(local)。

最后,您可以删除 LocalDateTime 的时间部分并以 LocalDate 结束。

如果使用 java 8,您可以执行以下操作

Instant instantOfNow = Instant.now();
LocalDate localDate 
    = LocalDateTime.ofInstant(instantOfNow, ZoneOffset.UTC).toLocalDate();
 Instant instant = Instant.now();   
 LocalDate localDate = LocalDate.ofInstant(instant, ZoneOffset.UTC);

上面的代码对我有用。

完成运行示例,Java8兼容:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

class Scratch {

  public static void main(String[] args) {
    Instant now = Instant.now();
    LocalDateTime ldt = now.atZone(ZoneId.systemDefault()).toLocalDateTime();
    System.out.println(ldt);
  }
}