如何在Java中将ZonedDateTime转换为毫秒?

32

我正在尝试使用以下代码将ZonedDateTime转换为毫秒。

LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zonedDateTime =ldt.atZone(ZoneId.of(""Asia/Kolkata""));
zonedDateTime.toInstant().toEpochMilli();

但是这个返回基于本地时间的毫秒,并且没有考虑ZoneId。

假设有一个 LocalDateTime("2019-04-10T05:30")。如果我将它转换为带有Zone id ("Asia/Kolkata") 的ZonedDateTime,那么我得到 ("2019-04-10T05:30+05:30[Asia/Kolkata]")。然后我将其转换为EpochMilli (1554854400000) = ("Wed Apr 10 2019 00:00:00") 在UTC中。


2
你能否稍微澄清一下你得到了什么输出以及你期望得到什么?目前代码的问题还不是很清楚。你现在的做法应该是可行的。 - TiiJ7
假设有一个 LocalDateTime("2019-04-10T05:30")。如果我将其转换为带有时区 ID ("Asia/Kolkata") 的 ZonedDateTime,则会得到 ("2019-04-10T05:30+05:30[Asia/Kolkata]")。然后我将其转换为 EpochMilli (1554854400000) = ("Wed Apr 10 2019 00:00:00") 在 UTC 中。 - Arun
3
欢迎来到 Stack Overflow。我不清楚你想要实现什么,或者你期望的结果是什么。如果你不在亚洲/加尔各答时区,那么你肯定无法找到当前的纪元时间。请提供更多关于你想要实现什么、你看到了什么值以及你期望看到什么的信息。 - Jon Skeet
4
好的,2019-04-10T05:30+05:30和2019-04-10T00:00:00Z表示同一时间点。你期望得到什么结果,为什么? - Jon Skeet
感谢提供补充信息。这些信息总是受欢迎的,您应该将其添加到您的问题中,而不是在评论中。只有这一次我替您添加了它。 - Ole V.V.
显示剩余3条评论
2个回答

60
您正在使用 Instant 来获取毫秒表示。 Instant 不基于时区。现在,纪元时间是基于 "1970-01-01T00:00:00Z" 的,因此您不应该在其中包含时区。
如果您想从纪元值创建 ZonedDateTime,您可以简单地在该纪元时间创建一个 Instant,然后用您希望的时区创建一个 ZonedDateTime
//Let's create our zone time (just to keep your logic
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zonedDateTime =ldt.atZone(ZoneId.of("Asia/Kolkata"));

//Then get the epoch on GMT
long e = zonedDateTime.toInstant().toEpochMilli();

Instant i = Instant.ofEpochMilli(e);
System.out.println(ZonedDateTime.ofInstant(i, ZoneId.systemDefault()));
System.out.println(ZonedDateTime.ofInstant(i, ZoneId.of("Asia/Kolkata")));

2019年04月12日05:10:31.016+02:00[欧洲/巴黎]
2019年04月12日08:40:31.016+05:30[亚洲/加尔各答]

注意:上面的代码不应该像这样使用,获取LocalDateTime然后ZonedDateTime再创建Instant是没有必要的。这只是为了说明即使有时区,在某个时刻它也会“丢失”。
请使用:

long e = Instant.now().toEpochMilli();

这个问题是关于将ZonedDateTime转换为毫秒的。在指定的时区中,它在哪里进行毫秒转换? - Ram
试试这个,它确实能够达到目的。https://dev59.com/UmAg5IYBdhLWcg3w9e0y - Ram
@MAC,虽然我已经有些遗忘了,但这里的重点是要证明预期值并非“基于区域”。请注意,你分享的解决方案确实可行(在第二个方案中),但它变成了一个“带时区的纪元时间”,稍后转换可能会出现一些问题。因为你需要数值和时区才能处理它。 - AxelH

5
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zonedDateTime =ldt.atZone(ZoneId.of("UTC"));
zonedDateTime.toInstant().toEpochMilli();

2
欢迎来到SO!您能解释一下这个解决方案是如何解决问题的,以及为什么它是帮助OP和未来访问者的好解决方案吗?谢谢。 - ggorlen

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