您能不能说明一下如何为默认系统时区和给定时区获得以毫秒为单位的正确纪元时间?
给定1。时区:GMT + 3
2。下面的代码片段:
import java.time.*;
public class Main {
public static void main(String[] args) {
System.out.println(LocalDateTime
.now()
.atZone(ZoneOffset.UTC)
.toInstant()
.toEpochMilli()
);
System.out.println(LocalDateTime
.now()
.atZone(ZoneOffset.of("+3"))
.toInstant()
.toEpochMilli()
);
System.out.println(System.currentTimeMillis());
}
}
3。输出:
1444158955508
1444148155508
1444148155508
4。用于System.currentTimeMillis()的JavaDoc,它告诉返回值将是当前时间与1970年1月1日UTC午夜之间的差值,以毫秒为单位。
,
为什么-
LocalDateTime
在GMT+3
时的输出与System.currentTimeMillis()
时的输出相同,尽管System.currentTimeMillis()
的文档提到UTC
? -
LocalDateTime
在UTC
的输出不同于System.currentTimeMillis()
,尽管System.currentTimeMillis()
的文档提到UTC
?
System.currentTimeMillis()
和Instant.toEpochMilli()
都返回自Unix纪元以来的毫秒数。这并不"在"任何特定的时区,尽管Unix纪元通常表示为"UTC时间1970年1月1日午夜"。但瞬间只是时间中的一瞬间,无论你在哪个时区,它都是一样的,但它会反映不同的当地时间。
LocalDateTime.atZone(UTC)
的输出不同,因为你说"取本地日期和时间,并将其转换为即时,就好像它在UTC时区"-即使当你创建LocalDateTime
时,你隐式地在UTC+3时区这样做…这就是为什么它是"错误的"。
LocalDateTime.now()
取系统默认时区中的本地日期和时间。因此,如果您的时区是UTC+3,当前时刻是2015-10-06T16:57:00Z,那么LocalDateTime.now()
将返回.2015-10-06T19:57:00
。我们把它命名为localNow
…
所以localNow.atZone(ZoneOffset.of("+3"))
将返回一个代表2015-10-06T19:57:00+03的ZonedDateTime
-换句话说,相同的本地日期/时间,但"知道"它比UTC早3小时…所以toInstant()
将返回一个代表2015-10-06T16:57:00Z的Instant
。太好了——我们还有当前的日期/时间。
但是localNow.atZone(ZoneOffset.UTC)
将返回一个代表2015-10-06T19:57:00Z的ZonedDateTime
-换句话说,相同的本地日期/时间,但"认为"它已经在UTC…所以toInstant()
将返回一个代表2015-10-06T19:57:00Z的Instant
。这根本不是当前时间(它是三小时后)。
短版:
没有办法计算LocalDateTime -> Instant
,你需要指定一个时区。使用时区,您可以得到ZonedDateTime
,并可以计算ZonedDateTime -> Instant
Instant == System.currentTimeMillis()
。
:
LocalDateTime是时钟上的时间(加上日期信息)。如果你不告诉我们你在哪个时区,这是不够的。东京的13:00和巴黎的13:00不是同一时刻。
一旦你添加一个时区到你的LocalDateTime,你得到一个ZonedDateTime,我们可以知道你实际上是在哪个瞬间的时间。你是13点在东京还是在巴黎?
要获得正确的Instant, ZonedDateTime的时区需要正确。如果现在是东京的13点,但你声称你是巴黎的13点,你会得到一个错误的瞬间。
LocalDateTime:
如果没有附加信息(如偏移量或时区),它不能表示时间线上的瞬间。
ZonedDateTime:
这个类处理从LocalDateTime的本地时间线到instant的即时时间线的转换。两条时间线之间的差异是与UTC/Greenwich的偏移量,用ZoneOffset表示。
要获得一个Instant,您需要首先将LocalDateTime转换为ZonedDateTime。如果你这样做是正确的(通过声明正确的时区),你的Instant将与System.currentTimeMillis()一致。
System.currentTimeMillis ():
当前时间与UTC时间1970年1月1日午夜之间的毫秒差。
- LocalDateTime在GMT+3的输出与System.currentTimeMillis()相同,尽管System.currentTimeMillis()的文档提到UTC?
如果你的时区是GMT+3,那么ZonedDateTime.toInstant()将给你正确的时间,因此与System.currentTimeMillis()一致
- LocalDateTime在UTC的输出不同于System.currentTimeMillis(),尽管System.currentTimeMillis()的文档提到UTC?
如果您的时区不是 UTC,那么ZonedDateTime.toInstant()将给您一个不正确的 Instant.
System.out.println("Output 1 : " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("Output 2 : " + System.currentTimeMillis());
输出1:1576047664910
输出2:1576047664911