为什么日期时间1-1-1970 00:00:00的毫秒数为负数?

时间:2019-11-28 10:50:21

标签: java date time

当我尝试获取表示(1-1-1970 01:00:00)的日期对象的时间时,它以负值返回毫秒。

 SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy HH:mm:ss"); Date
 date = sdf.parse("1/1/70 01:00:00");
 System.out.println(date.getTime());

上面的代码将打印负值。我想了解如何计算毫秒,以及该日期如何获得负值。

3 个答案:

答案 0 :(得分:3)

SimpleDateFormat是特定于时区的。使用dateFormat.parse(timesStamp)将返回特定时区的Date对象。因此它会因您当地时间与格林尼治标准时间的差异而被抵消。

要解决此问题,请尝试添加dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); =

答案 1 :(得分:3)

您的行Date date = sdf.parse("1/1/70 01:00:00");是时区敏感的。您处于GMT + 2时区,因此该时区的日期等于格林尼治标准时间1969年12月31日23:00:00。

答案 2 :(得分:2)

是的,当您使用旧的DateSimpleDateFormat时,这可能会造成混淆。解释是您的毫秒值是从纪元开始计算的,并且纪元在UTC中定义为1970-01-01 00:00 UTC。因此,如果您所在的时区偏离UTC,则1970-01-01 00:00处于不同的时间点,不同的时刻,不同的时刻。因此,取决于您是在UTC之前还是之后,毫秒值将小于或大于0。

使用现代Java日期和时间API java.time时,事情可能会变得更加清晰。该API邀请我们在相关时区明确显示时区,这有助于避免混淆。例如,尝试以下方法:

public static void printMilliseconds(ZoneId zone) {
    LocalDateTime dateTime = LocalDateTime.of(1970, Month.JANUARY, 1, 0, 0);
    ZonedDateTime zdt = dateTime.atZone(zone);
    System.out.println("In time zone: " + zdt);
    Instant i = zdt.toInstant();
    System.out.println("As Instant: " + i);
    long milliseconds = i.toEpochMilli();
    System.out.println("Milliseconds since the epoch: " + milliseconds);
}

假设您的时区为亚洲/加尔各答,那么将该时区传递给方法。

    printMilliseconds(ZoneId.of("Asia/Kolkata"));

然后输出为:

In time zone: 1970-01-01T00:00+05:30[Asia/Kolkata]
As Instant: 1969-12-31T18:30:00Z
Milliseconds since the epoch: -19800000

Instant以UTC打印(以尾随Z表示),因此我们可以看到印度的时间对应于纪元前五个半小时,即-19 80万毫秒。

对于格林威治以西的时区,我们得到一个正值。让我们尝试一下America / Mexico_City。

In time zone: 1970-01-01T00:00-06:00[America/Mexico_City]
As Instant: 1970-01-01T06:00:00Z
Milliseconds since the epoch: 21600000

为了完整起见,UTC本身。这应该给出0(零)。让我们看看。

    printMilliseconds(ZoneOffset.UTC);
In time zone: 1970-01-01T00:00Z
As Instant: 1970-01-01T00:00:00Z
Milliseconds since the epoch: 0

不要使用旧的课程

DateSimpleDateFormat的设计很差,这为您的困惑提供了很多解释。我建议我们不再使用它们。

链接

Oracle tutorial: Date Time解释了如何使用java.time。