JSR 310 :: System.currentTimeMillis() 与 Instant.toEpochMilli() :: TimeZone

2022-01-16 00:00:00 datetime timezone java-8 java java-time

您能否说明如何为默认系统时区和给定时区获取正确的纪元时间(以毫秒为单位).

Could you please shed some light on how to obtain correct epoch time in milliseconds for a default system timezone and given timezone.

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 表示返回值将是当前时间与 UTC 1970 年 1 月 1 日午夜之间的差异,以毫秒为单位.

  1. GMT+3LocalDateTime 的输出与 System.currentTimeMillis() 的输出相同,尽管 LocalDateTime 的文档code>System.currentTimeMillis() 提到 UTC?
  2. UTCLocalDateTime 输出不同于 System.currentTimeMillis(),尽管 System.currentTimeMillis 的文档() 提到 UTC?
  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?
  2. the output of the LocalDateTime at UTC differs from System.currentTimeMillis(), although the docs for the System.currentTimeMillis() mention UTC?

推荐答案

System.currentTimeMillis()Instant.toEpochMilli() 都返回自Unix 时代.尽管 Unix 纪元通常表示为UTC 时间 1970 年 1 月 1 日午夜",但这并不在"任何特定时区.但是瞬间只是时间的瞬间,无论您在哪个时区都是一样的 - 但它会反映不同的本地时间.

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.

LocalDateTime.atZone(UTC) 的输出不同,因为您说的是获取本地日期和时间,并将其转换为即时就好像它在 UTC 时间zone" - 即使您在创建 LocalDateTime 时隐含地在 UTC+3 时区这样做......这就是它错误"的原因.

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.now() 采用系统默认时区中的本地日期和时间.因此,如果您的时区是 UTC+3,则当前时间是 2015-10-06T16:57:00Z,那么 LocalDateTime.now() 将返回 .2015-10-06T19:57:00.我们称之为 localNow...

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...

所以 localNow.atZone(ZoneOffset.of("+3")) 将返回一个 ZonedDateTime 代表 2015-10-06T19:57:00+03 - in换句话说,相同的本地日期/时间,但知道"它比 UTC 早 3 小时......所以 toInstant() 将返回一个代表 2015-10 的 Instant-06T16:57:00Z.太好了 - 我们还有当前的日期/时间.

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.UTC) 将返回代表 2015-10-06T19:57:00Z 的 ZonedDateTime - 换句话说,相同的本地日期/时间,但认为"它已经在 UTC...所以 toInstant() 将返回一个代表 2015-10-06T19:57:00Z 的 Instant .. 这是根本不是当前时间(三小时后).

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).

相关文章