将LocalDateTime转换为Instant需要一个ZoneOffset。为什么呢?

10

我需要将一个 LocalDateTime 对象转换成一个新的 Instant 对象。

我发现 LocalDateTime 有一个 toInstant 方法,但它需要一个 ZoneOffset 参数。

我不太清楚如何使用它,或者 ZoneOffset 是什么意思。


请查看ZoneOffset - Mark
文档中指出:纪元秒是从标准Java纪元时间1970-01-01T00:00:00Z开始计算的。这里的Z代表“Zulu时区”。重要的是你需要一个时区,这样Java才能正确地计算给定时间的瞬间。 - jrook
2个回答

20

你无法直接将LocalDateTime转换为Instant,因为LocalDateTime可以表示许多瞬间。它不代表特定的时间瞬间。

这是一个LocalDateTime

23/10/2018 09:30:00

通过上面的内容,你能准确地知道它所指的时间是哪个时刻吗?不行。因为在英国的时间和中国的时间是不同的。

要想知道那个时间所指的具体时刻,你还需要知道它与协调世界时(UTC)相差多少小时,这就是ZoneOffset的基本含义。

例如,如果偏移量为8小时,则可以这样写:

localDateTime.toInstant(ZoneOffset.ofHours(8))

或者,如果您知道您总是想要该本地日期时间在当前时区中的区偏移量,您可以使用以下内容替换 ZoneOffset.ofHours(8)

ZoneId.systemDefault().getRules().getOffset(localDateTime)

在将偏移量转换为时间戳之前,您应该考虑要使用哪种偏移量。


好的解释。您能否添加一种编程方式来确定本地系统的偏移量? - ernest_k
1
我在服务器上。我怎样可以获得当前服务器的“ZoneOffset”? - Jordi
1
很棒的答案!我知道问题是关于为什么你必须使用ZoneOffset,但既然你需要,这里有一个简单的方法:localDateTime.atZone(ZoneId.systemDefault()).toInstant() - Cassio Luis Felippe

2

你可以尝试这个:

LocalDateTime dateTime = LocalDateTime.of(2018, Month.OCTOBER, 10, 31, 56);
Instant instant = dateTime.atZone(ZoneId.of("Europe/Rome")).toInstant();
System.out.println(instant);

1
虽然它并没有真正回答标题中的“为什么”,但它清楚地展示了解决问题的正确方法(当然,必须替换正确的时区)。 - Ole V.V.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接