请您详细说明如何获得默认系统时区和给定时区的正确纪元时间(以毫秒为单位)。
1。 TimeZone: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日午夜时间之间的差值(以毫秒为单位)。
LocalDateTime
GMT+3
的输出与System.currentTimeMillis()
的输出相同,但System.currentTimeMillis()
提及UTC
的文档?LocalDateTime
UTC
的输出与System.currentTimeMillis()
不同,尽管System.currentTimeMillis()
的文档提及UTC
?答案 0 :(得分:32)
System.currentTimeMillis()
和Instant.toEpochMilli()
都返回自Unix纪元以来的毫秒数。虽然Unix纪元通常表示为“1970年1月1日午夜,UTC”,但它并非“在”任何特定时区。但是瞬间只是一个瞬间,并且与您所处的时区相同 - 但它会反映当地时间的不同。
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"))
将返回ZonedDateTime
代表2015-10-06T19:57:00 + 03 - 换句话说,相同的本地日期/时间,但“知道”提前3小时UTC ...所以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
..这不是当前时间(三小时内)。
答案 1 :(得分:1)
简短版本:
无法计算LocalDateTime -> Instant
,需要指定时区。
使用时区,您将获得ZonedDateTime
并可以计算ZonedDateTime -> Instant
Instant == System.currentTimeMillis()
,如果ZonedDateTime的时区等于系统默认时区。
长版:
LocalDateTime是时钟上的时间(加上日期信息)。如果您不告诉我们您所在的时区,那还不够。东京的13:00点与巴黎的13:00点是同一时间。
将时区添加到LocalDateTime后,您将获得一个ZonedDateTime,我们可以知道您实际在哪一个即时时间。例如。您是在东京还是巴黎的13:00?
要获取正确的Instant,ZonedDateTime的时区必须正确。如果东京时间是13:00,但您声称自己是巴黎的13:00,则会收到错误的“ Instant”(即时)。
如果没有其他信息(例如偏移量或时区),则无法在时间轴上表示时刻。
此类处理从LocalDateTime的本地时间线到Instant的即时时间线的转换。两条时间线之间的差异是相对于UTC /格林威治的偏移量,由ZoneOffset表示。
要获取Instant,您需要先将LocalDateTime转换为ZonedDateTime。如果您正确地做到了这一点(通过指出正确的时区),则Instant将同意System.currentTimeMillis()。
当前时间与UTC 1970年1月1日午夜之间的差值(以毫秒为单位)。
如果您的时区是格林尼治标准时间+3,那么ZonedDateTime.toInstant()将为您提供正确的即时消息,因此同意System.currentTimeMillis()
如果您的时区不是世界标准时间(UTC),那么ZonedDateTime.toInstant()将为您提供不正确的即时信息。
答案 2 :(得分:0)
System.out.println("Output 1 : " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("Output 2 : " + System.currentTimeMillis());
输出1:1576047664910
输出2:1576047664911