为什么通过 SimpleDateFormat 解析时 Java 纪元时间会减少 30 分钟

Ada*_*ise 0 java epoch simpledateformat

不知何故,解析日期时间字符串并将其转换为纪元后的毫秒数在不同环境中的工作方式有所不同。时区之类的东西似乎有问题。理论上,该字符串应表示自纪元以来的 0 秒:“1970-01-01T00:00:00Z”

实际上,在开发人员机器上,这个时间神秘地是 30 分钟(18000000 毫秒)。

    /**
     * This really ought to return 0, but locally it returns 30 minutes worth of milliseconds.
     * @return The milliseconds since the common epoch. Really ought to be zero, but isn't always.
     */
    public long determineMysteriousMachineTimeDelta()  {
        String strDateOfEpochStart = "1970-01-01T00:00:00Z";
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        Date dateStartOfEpoch = null;
        try {
            dateStartOfEpoch = format.parse(strDateOfEpochStart);

        } catch (ParseException e) {
            return -1;
        }
        return dateStartOfEpoch.getTime();
    }
Run Code Online (Sandbox Code Playgroud)

谢谢!

Bas*_*que 5

太长了;博士

\n
Instant.parse( "1970-01-01T00:00:00Z" )\n
Run Code Online (Sandbox Code Playgroud)\n

Z, 绝不\'Z\'

\n

Z切勿在格式模式中将引号括起来。

\n

该字母表示与 UTC 的偏移量为零时-分-秒。发音为 \xe2\x80\x9cZulu\xe2\x80\x9d。

\n

您的引号表示 \xe2\x80\x9cexpect 此文本,但忽略它\xe2\x80\x9d。所以你的格式化模式会丢弃重要的信息。

\n

避免遗留日期时间类

\n

切勿使用SimpleDateFormat, Calendar,Date类。这些都是遗留类,并且存在严重缺陷。它们在几年前就被 JSR 310 中定义的现代java.time类所取代。

\n

java.time

\n

您的输入字符串符合ISO 8601标准。

\n

在解析/生成文本时,java.time类默认使用该标准。因此无需指定格式模式。

\n

要表示 UTC 中的时刻,请使用Instantclass。

\n
Instant instant = Instant.parse( "1970-01-01T00:00:00Z" ) ;\n
Run Code Online (Sandbox Code Playgroud)\n

从纪元开始计数

\n

询问自 UTC (1970-01-01T00:00Z) 中看到的 1970 年第一个时刻的纪元参考以来的毫秒数。

\n

因此,在您的示例中,我们预计计数为零毫秒。

\n
long millis = instant.toEpochMilli() ;\n
Run Code Online (Sandbox Code Playgroud)\n

请参阅在 Ideone.com 上运行的此代码。

\n

顺便说一句,请注意这里的数据丢失 \xe2\x80\x94\xc2\xa0anInstant解析为纳秒,比毫秒要精细得多。

\n