在 Java 我如何将自纪元以来的秒数转换为自 1970 年 1 月 1 日以来的毫秒数,00:00:00 GMT

In Java how do I convert from seconds since epoch to milliseconds since January 1, 1970, 00:00:00 GMT

简而言之:

我有一个时代,我想从 January 1, 1970, 00:00:00 GMT 开始,正如 java.util.Date 所期望的那样。

此代码有助于说明我的问题:

import java.util.Date;
import java.util.Locale;

import org.junit.Test;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class TimeHelp {

    private String format = "EEE MMM dd HH:mm:ss yyyy";

    public SimpleDateFormat asSimpleDateFormat() {
        return new SimpleDateFormat(format, Locale.ENGLISH);
    }

    public DateTimeFormatter asDateTimeFormatter() {
        return DateTimeFormatter.ofPattern(format, Locale.ENGLISH);
    }

    @Test
    public void test() throws Exception {
        System.out.println(ZoneId.systemDefault());
        String s = "Sun Apr 04 02:00:01 2010";
        long t1 = asSimpleDateFormat().parse(s).getTime();

        ZonedDateTime zoned = LocalDateTime.parse(s, asDateTimeFormatter())
                    .atZone(ZoneId.systemDefault());
        long t2 = zoned.toEpochSecond() * 1000;

        long t3 = Date.from(zoned.toInstant()).getTime();

        long t4 = zoned.toInstant().toEpochMilli();

        System.out.println("t1 " + t1);
        System.out.println("t2 " + t2);
        System.out.println("t3 " + t3);
        System.out.println("t4 " + t4);
        System.out.println("Difference in minutes " + Math.abs(t1 - t2)/1000/60);
    } 
}

然后输出:

Australia/Sydney
t1 1270310401000
t2 1270306801000
t3 1270306801000
t4 1270306801000
Difference in minutes 60

请注意 t1 与其他时间不同,我认为是因为 t1 是 GMT 而其他时间都是 UTC。

如果我使用 SimpleDateFormat long 的值不同于如果我使用 DateTimeFormatter 得到一个 ZonedDateTime 然后我调用 toEpochSecond().

出于某种原因,我想得到一个 ZonedDateTime,我想将其转换为 Date,但看起来这样的事情行不通,因为 Date 在GMT 不是 UTC.

引用 timeanddate.com:

When local daylight time was about to reach Sunday, April 4, 2010, 3:00:00 am clocks were turned backward 1 hour to Sunday, April 4, 2010, 2:00:00 am local standard time instead.

这意味着 Sun Apr 04 02:00:01 2010 那天发生了 两次 。那么这 2 个你中了哪一个?

使用 SimpleDateFormat 你会得到 later 一个,尽管没有记录。

使用 ZonedDateTime 你会得到 更早的 一个:

For Overlaps, the general strategy is that if the local date-time falls in the middle of an Overlap, then the previous offset will be retained. If there is no previous offset, or the previous offset is invalid, then the earlier offset is used, typically "summer" time.. Two additional methods, withEarlierOffsetAtOverlap() and withLaterOffsetAtOverlap(), help manage the case of an overlap.