2

我听说Unix时间不包括“闰秒”。而且我还听说Java Calendar API 不包括闰秒。

自 1972 年以来,闰秒增加了 27 秒。Unix 时间开始于 1970-01-01 00:00:00 (UTC)。

所以,我认为当前的 UTC 时间和 Unix 时间之间有 27 秒的差异。

为了澄清我的想法,我做了一些如下的实验。1614766198 是 2021-03-03 10:10:00 (UTC+0) 的 Unix 时间

import java.util.Calendar;
import java.util.TimeZone;

public class CanendarTest {
    public static void main(String[] args) throws InterruptedException {

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        
        cal.setTimeInMillis(1614766198L * 1000);
        System.out.println(cal.get(Calendar.YEAR));
        System.out.println(cal.get(Calendar.MONTH));
        System.out.println(cal.get(Calendar.DAY_OF_MONTH));
        System.out.println(cal.get(Calendar.HOUR_OF_DAY));
        System.out.println(cal.get(Calendar.MINUTE));
        System.out.println(cal.get(Calendar.SECOND));
    }
}

上面代码的结果是

output
2021
2
3
10
9
58

输出看起来像“2021-03-03 10:09:58”。

所以,我的问题是,为什么 Java Calendar API 从 1970-01-01 00:00:00 (UTC) 返回 2 秒的差异而不是 27 秒的差异?

4

1 回答 1

3

1614766198 是 2021-03-03 10:10:00 (UTC+0) 的 Unix 时间

这是不正确的。以下 UNIX 命令

TZ=UTC date -r 1614766198

输出

Wed  3 Mar 2021 10:09:58 UTC

java.time

java.util日期时间 API 及其格式化 API已SimpleDateFormat过时且容易出错。建议完全停止使用它们并切换到现代 Date-Time API *

使用java.time现代日期时间 API 的解决方案:

import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        Instant instant = Instant.ofEpochSecond(1614766198);
        System.out.println(instant);
    }
}

输出:

2021-03-03T10:09:58Z

ONLINE DEMO

An代表UTCInstant时间线上的一个瞬时点。输出中的 是零时区偏移的时区指示符。它代表 Zulu 并指定时区(时区偏移量为小时)。ZEtc/UTC+00:00

从Trail: Date Time了解有关现代日期时间 API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

于 2021-07-02T17:57:34.407 回答