如何从 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);
请注意 日期是 22 日而不是 23 日,因为该时区使用的偏移量比 UTC 早几个小时。
2020-01-22
Java 8
如果您正在使用 Java 8,那么您可以使用 ZonedDateTime
的 toLocalDate()
方法:
yourInstant.atZone(yourZoneId).toLocalDate()
其他答案提供了转换的机制,但我想补充一些关于这种转换含义的背景知识,希望这有助于解释为什么它以这种方式工作。
LocalDate
和 Instant
看起来很相似——它们都包含没有时区信息的日期(/时间)信息。但是,它们的含义却大不相同。
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);
}
}
我有一个 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);
请注意 日期是 22 日而不是 23 日,因为该时区使用的偏移量比 UTC 早几个小时。
2020-01-22
Java 8
如果您正在使用 Java 8,那么您可以使用 ZonedDateTime
的 toLocalDate()
方法:
yourInstant.atZone(yourZoneId).toLocalDate()
其他答案提供了转换的机制,但我想补充一些关于这种转换含义的背景知识,希望这有助于解释为什么它以这种方式工作。
LocalDate
和 Instant
看起来很相似——它们都包含没有时区信息的日期(/时间)信息。但是,它们的含义却大不相同。
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);
}
}