java JSR 310 :: System.currentTimeMillis() 与 Instant.toEpochMilli() :: TimeZone
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32975392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSR 310 :: System.currentTimeMillis() vs Instant.toEpochMilli() :: TimeZone
提问by szhem
Could you please shed some light on how to obtain correct epoch time in milliseconds for a default system timezone and given timezone.
您能否解释一下如何为默认系统时区和给定时区获得正确的纪元时间(以毫秒为单位)。
Given
给定的
1. TimeZone: GMT+3
1. 时区:GMT+3
2. The following code snippet:
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. Output:
3. 输出:
1444158955508
1444148155508
1444148155508
4. JavaDoc for System.currentTimeMillis()that tells that returned value will be the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
4. System.currentTimeMillis() 的JavaDoc,它告诉返回值将是当前时间与 UTC 时间 1970 年 1 月 1 日午夜之间的差值(以毫秒为单位)。
So, why
所以为什么
- the output of the
LocalDateTime
atGMT+3
is the same as ofSystem.currentTimeMillis()
, although the docs for theSystem.currentTimeMillis()
mentionUTC
? - the output of the
LocalDateTime
atUTC
differs fromSystem.currentTimeMillis()
, although the docs for theSystem.currentTimeMillis()
mentionUTC
?
LocalDateTime
at的输出与 的GMT+3
相同System.currentTimeMillis()
,尽管System.currentTimeMillis()
提到的文档UTC
?LocalDateTime
at的输出UTC
不同于System.currentTimeMillis()
,尽管System.currentTimeMillis()
提到的文档UTC
?
回答by Jon Skeet
Both System.currentTimeMillis()
and Instant.toEpochMilli()
return the number of milliseconds since the Unix epoch. That isn't "in" any particular time zone, although the Unix epoch is normally expressed as "midnight on January 1st 1970, UTC". But an instant is just an instant in time, and is the same whichever time zone you're in - but it will reflect a different local time.
双方System.currentTimeMillis()
并Instant.toEpochMilli()
自Unix纪元返回的毫秒数。这不是“在”任何特定时区,尽管 Unix 时代通常表示为“1970 年 1 月 1 日午夜,UTC”。但是瞬间只是时间上的瞬间,无论您在哪个时区都相同 - 但它会反映不同的当地时间。
The output of LocalDateTime.atZone(UTC)
differs because you're saying "Take the local date and time, and convert it to an instant as if it were in the UTC time zone" - even though when you created that LocalDateTime
you did so implicitly in the UTC+3 time zone... that's why it's "wrong".
的输出LocalDateTime.atZone(UTC)
不同,因为您说的是“获取本地日期和时间,并将其转换为一个瞬间,就好像它在 UTC 时区一样”-即使当您创建它时,LocalDateTime
您在 UTC+3 时间中隐式这样做区域......这就是为什么它是“错误的”。
LocalDateTime.now()
takes the local date and time in the system default time zone. So if your time zone is UTC+3, the current instant in time is 2015-10-06T16:57:00Z, then LocalDateTime.now()
will return .2015-10-06T19:57:00
. Let's call that localNow
...
LocalDateTime.now()
采用系统默认时区中的本地日期和时间。因此,如果您的时区是 UTC+3,则当前时刻为 2015-10-06T16:57:00Z,LocalDateTime.now()
则将返回.2015-10-06T19:57:00
. 让我们称之为localNow
...
So localNow.atZone(ZoneOffset.of("+3"))
will return a ZonedDateTime
representing 2015-10-06T19:57:00+03 - in other words, the same local date/time, but "knowing" that it's 3 hours ahead of UTC... so toInstant()
will return an Instant
representing 2015-10-06T16:57:00Z. Great - we still have the current date/time.
所以localNow.atZone(ZoneOffset.of("+3"))
将返回一个ZonedDateTime
代表 2015-10-06T19:57:00+03 - 换句话说,相同的本地日期/时间,但“知道”它比 UTC 早 3 小时......所以toInstant()
将返回一个Instant
代表 2015-10 -06T16:57:00Z。太好了 - 我们还有当前的日期/时间。
But localNow.atZone(ZoneOffset.UTC)
will return a ZonedDateTime
representing 2015-10-06T19:57:00Z - in other words, the same local date/time, but "thinking" that it's already in UTC... so toInstant()
will return an Instant
representing 2015-10-06T19:57:00Z.. which isn't the current time at all (it's in three hours).
但localNow.atZone(ZoneOffset.UTC)
将返回一个ZonedDateTime
代表 2015-10-06T19:57:00Z - 换句话说,相同的本地日期/时间,但“认为”它已经在 UTC 中......所以toInstant()
将返回一个Instant
代表 2015-10-06T19:57 :00Z .. 这根本不是当前时间(三小时后)。
回答by Roland
Short version:
简短版本:
There is no way to compute LocalDateTime -> Instant
, you need to specify a timezone.
With a timezone you get a ZonedDateTime
and can compute ZonedDateTime -> Instant
没有办法计算LocalDateTime -> Instant
,你需要指定一个时区。使用时区,您可以获得一个ZonedDateTime
并且可以计算ZonedDateTime -> Instant
Instant == System.currentTimeMillis()
if the timezone of the ZonedDateTime equals the system default time zone.
Instant == System.currentTimeMillis()
如果 ZonedDateTime 的时区等于系统默认时区。
Long version:
长版:
LocalDateTime is the time on your clock(plus date information). Which is not enough if you don't tell us which timezone your are in. 13:00 o'clock in Tokyo is not the same Instant as 13:00 o'clock in Paris.
LocalDateTime 是您时钟上的时间(加上日期信息)。如果您不告诉我们您所在的时区,这还不够。东京的 13:00 点与巴黎的 13:00 点不是同一个 Instant。
Once you add a timezone to your LocalDateTime you get a ZonedDateTime and we can know in which Instant of time you actually are. E.g. are you 13:00 o'clock in Tokyo or in Paris?
将时区添加到 LocalDateTime 后,您将获得 ZonedDateTime,我们可以知道您实际上处于哪个时刻。例如,您是 13:00 点在东京还是在巴黎?
To get the correct Instant the timezone of the ZonedDateTime needs to be correct. If it is 13:00 o'clock in Tokyo but you claim that you are 13:00 o'clock in Paris you will get a wrong Instant.
要获得正确的 Instant, ZonedDateTime 的时区需要正确。如果在东京是 13:00 点,而你声称你在巴黎是 13:00 点,你会得到一个错误的 Instant。
本地日期时间:
It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
如果没有偏移量或时区等附加信息,它就无法表示时间线上的瞬间。
This class handles conversion from the local time-line of LocalDateTime to the instant time-line of Instant. The difference between the two time-lines is the offset from UTC/Greenwich, represented by a ZoneOffset.
此类处理从 LocalDateTime 的本地时间线到 Instant 的即时时间线的转换。两条时间线之间的差异是与 UTC/格林威治的偏移量,由 ZoneOffset 表示。
To get an Instantyou need to convert LocalDateTime to ZonedDateTime first. If you did this correctly(by stating the correct timezone) your Instant will agree with System.currentTimeMillis().
要获得Instant,您需要先将 LocalDateTime 转换为 ZonedDateTime。如果您正确执行此操作(通过说明正确的时区),您的 Instant 将同意 System.currentTimeMillis()。
the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
当前时间与 UTC 时间 1970 年 1 月 1 日午夜之间的差值(以毫秒为单位)。
- the output of the LocalDateTime at GMT+3 is the same as of System.currentTimeMillis(), although the docs for the System.currentTimeMillis() mention UTC?
- GMT+3 时 LocalDateTime 的输出与 System.currentTimeMillis() 的输出相同,尽管 System.currentTimeMillis() 的文档提到了 UTC?
If your timezone is GMT+3 then ZonedDateTime.toInstant()will give you the correct Instant and therefore agree with System.currentTimeMillis()
如果您的时区是 GMT+3,则ZonedDateTime.toInstant()将为您提供正确的 Instant,因此同意System.currentTimeMillis()
- the output of the LocalDateTime at UTC differs from System.currentTimeMillis(), although the docs for the System.currentTimeMillis() mention UTC?
- UTC 时 LocalDateTime 的输出与 System.currentTimeMillis() 不同,尽管 System.currentTimeMillis() 的文档提到了 UTC?
If your timezone is notUTC then ZonedDateTime.toInstant()will give you an incorrectInstant.
如果您的时区不是UTC,则ZonedDateTime.toInstant()会给您一个不正确的Instant。
回答by StinkyMadness
System.out.println("Output 1 : " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("Output 2 : " + System.currentTimeMillis());
Output 1 : 1576047664910
输出 1:1576047664910
Output 2 : 1576047664911
输出 2:1576047664911