如何使 date.getTime() 返回 UTC 时间?tl;博士 Date始终采用 UTC 格式java.time关于 java.time

2022-09-02 00:02:53

我有一个表示 UTC 时间的 Date 对象。当我使用 getTime() 方法获取此对象的长整型值时,返回的值对应于我们的本地时间(美国中部)。获取与原始 UTC 时间相对应的值的正确方法是什么?

谢谢


答案 1

tl;博士

Instant.now()

...和。。。

Instant.ofEpochMilli( n ) 

...和。。。

instant.toEpochMilli()

Date始终采用 UTC 格式

当我使用 getTime() 方法获取此对象的长整型值时,返回的值对应于我们的本地时间(美国中部)。

否,从 Date::getTime() 返回的值始终对应于 UTC(在此上下文中与 GMT 几乎相同)。引用类文档:

返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。

所以你的问题是荒谬的,因为a已经在UTC中了。无需“取回与原始UTC时间相对应的值”,Date

您可能会将 的行为与方法的行为混淆。该方法在生成 String 的过程中令人讨厌且令人困惑地应用当前默认时区。因此,字符串输出以时区显示,而实际上没有要设置或从自身获取的时区。(实际上在深处有一个区域,但这与这里的讨论无关。这门课是一团糟!getTimetoStringtoStringDateDate

java.time

做到这一点的现代方法是使用java.time类。

Table of date-time types in Java, both modern and legacy

Instant

Instant 类以 UTC 格式表示时间轴上的某个时刻,分辨率为纳秒(最多九 (9) 位小数)。

获取当前时刻。

Instant instant = Instant.now();

您可以通过调用添加到旧日期时间类的新转换方法之一,将 转换为其新式替换。只需打电话,相当容易。DatetoInstant

Instant instant = myJavaUtilDate.toInstant();  

我根本不建议使用从纪元计数作为跟踪时间的方法。坚持使用java.time对象。在 Java 外部时,使用 ISO 8601 格式序列化为文本。

但是,如果必须,可以提取自 1970-01-01T00:00:00Z 纪元以来的毫秒数。请注意,这可能涉及数据丢失!An 具有纳秒的更精细分辨率。因此,达到毫秒可能会减少一秒的一小部分。Instant

long millisecondsSinceEpoch = instant.toEpochMilli();  // Caution: Possible data-loss in going from nanoseconds to milliseconds.

从计数转到另一个方向。Instant

Instant instant = Instant.ofEpochMilli( millisecondsSinceEpoch ) ;

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


答案 2

该类具有用于设置首选时区的方法,并且有一个具有 UTC 时间设置的时区类。DateFormat

因此,例如,

SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Date yourUtcDate = sdf.parse(yourOriginalDate);