Java中使用java.util.Date的不同时间转换

Different time conversion by using java.util.Date in Java

我正在使用以下代码通过在 Java.

中使用 java.util.Date class 将纪元转换为时间
Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
System.out.println("Date obj :" + date);

以下是 运行 两个不同时区服务器上的相同代码的输出:

在 EDT 服务器上-

Date obj :Fri Oct 09 11:45:00 EDT 2020

在 IST 服务器上 -

Date obj :Fri Oct 09 21:15:00 IST 2020

为什么会这样?我只是经过毫秒。此数据应该在所有服务器上被视为 21:15。为什么 Date class 改变了数据?

请分享一段代码示例,无论服务器的时区如何,都可以获得相同的时间数据。

一个 Date 对象表示一个特定的瞬间,用自 Unix 纪元以来的给定毫秒数表示。

toString() 方法根据默认时区将该瞬间转换为 本地 时间。并不是 Date 值本身“有”时区——只是 toString() 使用了默认时区。

This data is supposed to be treated as 21:15 on all servers.

这表明您希望在所有服务器中使用印度时区,至少在转换即时显示时是这样。在对您的应用程序一无所知的情况下,我们只能说这些……除了“不要使用 java.util.Datejava.util.Calendar;请改用 java.time 类”。它们 设计得更好 ,您不太可能 运行 遇到这样的问题。

java.time

我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。

    long scheduledTime = 1_602_258_300_000L;
    Instant pointInTime = Instant.ofEpochMilli(scheduledTime);
    System.out.println(pointInTime);

此片段的输出在所有时区的所有服务器上都是相同的:

2020-10-09T15:45:00Z

既然你想要21:15,请指定印度的时区:

    ZoneId serverTimeZone = ZoneId.of("Asia/Kolkata");
    ZonedDateTime dateTime = pointInTime.atZone(serverTimeZone);
    System.out.println(dateTime);

2020-10-09T21:15+05:30[Asia/Kolkata]

出了什么问题?

纪元是独立于时区的一个时间点。所以毫秒数也表示一个时间点。在您的情况下,该时间点是 2020 年 10 月 9 日星期五 15:45:00 UTC。在那个时间点,印度是 21:15,北美东海岸是 11:45。过时的 Date class 的一个令人困惑的特征是,一方面它只代表一个时间点,另一方面它的 toString 方法获取 JVM 的时区设置并使用它用于呈现要返回的字符串,从而给您一种错误的印象,即您在不同时区得到不同的 Date 个对象,而实际上它们是相等的。

链接

正如其他人所指出的,您现在应该使用 java.time 包处理时间。如果您查看 java.util.DatetoString() 方法的文档,它说它将 Date 对象转换为以下形式的字符串:

EEE MMM d m dd hh:mm:ss zzz yyyy

后台好像是下面的代码运行:

public String toString(){
    Date date=this;
    SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
    simpleDateFormat.setTimeZone(TimeZone.getDefault());  //This line is important.
    return simpleDateFormat.format(date);
}

现在,如果您想为特定时区格式化 Date 对象,您可以执行相同的操作,包括设置时区:

Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("IST")); 
String dateStr = simpleDateFormat.format(date);
System.out.println("Date obj :" + dateStr);