我有一个从应该是LocalDate
的来源收到的Instant
,但在LocalDate
类中没有看到任何将Instant
转换为LocalDate
的方法。
最佳的方法是什么?
我有一个从应该是LocalDate
的来源收到的Instant
,但在LocalDate
类中没有看到任何将Instant
转换为LocalDate
的方法。
最佳的方法是什么?
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);
请注意,由于该时区使用UTC之前的几个小时偏移量,日期为22日而不是23日。
2020年1月22日
如果您使用的是Java 8,则可以使用ZonedDateTime
的toLocalDate()
方法:
yourInstant.atZone(yourZoneId).toLocalDate()
其他答案提供了这种转换的机制,但我想补充一些有关此类转换含义的背景,希望能说明它为什么以这种方式工作。
LocalDate
和Instant
看起来很相似——它们都保存了日期/(时间)信息,但没有时区信息。但是,它们具有非常不同的含义。
Instant
表示一个时间点的确切时间。该表示未明确包含任何时区,但隐式地指向UTC时间线。
LocalDateTime
(和LocalDate
)是有歧义的,因为它表示本地时间线上的一个时间点,隐含地指向本地时区。
因此,为了正确地将Instant
转换为LocalDateTime
(在概念上——其中部分步骤在实现中被打包成单个操作),您需要执行以下操作:
1.通过应用UTC时区信息将Instant
转换为ZonedDateTime
2. 将时区从UTC更改为本地时区(这意味着应用相关的时区偏移),从而获得另一个带有不同时区的ZonedDateTime
3.将ZonedDateTime
转换为LocalDateTime
,通过删除时区信息使时间区隐含(本地)。
最后,您可以去掉LocalDateTime
的时间部分,得到LocalDate
。
如果使用Java 8,您可以执行以下操作
Instant instantOfNow = Instant.now();
LocalDate localDate
= LocalDateTime.ofInstant(instantOfNow, ZoneOffset.UTC).toLocalDate();
你需要问自己想要将它转换为哪个时区偏移量,最有可能的是当你知道答案:
LocalDate.ofInstant(yourInstant, yourZoneOffSet)
编辑
刚刚意识到这只有在Java 9及以上版本才能实现,在Java 9之前请看其他答案
完整的运行示例,兼容Java 8:
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 instant = Instant.now();
LocalDate localDate = LocalDate.ofInstant(instant, ZoneOffset.UTC);
上面的代码对我有效。
ZoneOffset.UTC
,例如。 - PipoyourZoneId
应该是ZoneId.systemDefault()
,因为我们要转换成用户的本地日期。 - user924