问题描述
我正在使用下面的代码通过使用Java中的java.util.Date
类来进行时间到时间的转换。
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类会更改数据?
请共享示例代码,以获取相同的时间数据,而与服务器的时区无关。
解决方法
Date
对象表示特定的时间瞬间,以自Unix时代以来的给定毫秒数表示。
toString()
方法根据默认时区将该时间点转换为本地时间。并非Date
值本身“具有”时区-使用默认值的只是toString()
。
应该在所有服务器上将此数据视为21:15。
这建议您至少在转换即时时间以进行显示时,要在所有服务器中使用印度时区。在不了解您的应用程序的情况下,我们只能说...除了“不要使用java.util.Date
或java.util.Calendar
,而应使用java.time
类”。它们的设计更好,并且您遇到此类问题的可能性也较小。
java.time
我建议您使用现代Java日期和时间API java.time进行日期和时间工作。
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 [亚洲/加尔各答]
出了什么问题?
时期是一个时间点,与时区无关。因此毫秒数也表示一个时间点。对于您而言,该时间点是星期五9。2020年10月15:45:00 UTC。当时印度是21:15,北美东海岸是11:45。这是过时的Date
类的一个令人困惑的特征,一方面,它仅表示一个时间点;另一方面,其toString
方法捕获了JVM的时区设置,并使用它来呈现JVM。要返回的字符串,因此给人一种错误的印象,即实际上它们相等时,会在不同的时区中获得不同的Date
对象。
链接
- Oracle tutorial: Date Time解释如何使用java.time。
- Epoch & Unix Timestamp Conversion Tools,您可以在此处检查UTC / GMT和您自己所在时区的毫秒数。
正如其他人指出的那样,您现在应该使用java.time
包来处理时间。如果您查看toString()
的{{1}}方法的文档,它会说它将Date对象转换为以下形式的字符串:
EEE MMM d m dd hh:mm:ss zzz yyyy
就像下面的代码在后台运行一样:
java.util.Date
现在,如果要格式化某个时区的Date对象,则可以执行相同操作,包括设置时区:
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);
}