如何在过去的特定时间使用 UTC 创建 Date 对象?

How to create a Date object, using UTC, at a specific time in the past?

是否可以创建一个 java.util.Date 对象,该对象保证是 UTC 并且在过去的特定时间,比如一小时前或一天前,这是个好主意吗?

我已经查看了 Stack Overflow 问题 get date as of 4 hours ago 及其答案。但是我想避免必须添加更多依赖项,例如 jodaTime,并且接受的答案使用 System.currentTimeMillis(),这将是本地时区,不是吗?

您可以使用 java.time 包实现此目的,如下所示:

LocalDateTime localDateTime = LocalDateTime.now(ZoneOffset.UTC).minusHours(4);
Date date = Date.from(localDateTime.atZone(ZoneOffset.UTC).toInstant());

给出以下输出:

2018-01-31T14:58:28.908
Wed Jan 31 20:28:28 IST 2018     //20:28:28 IST is 14:58:28 UTC

这比我现在的时间晚 4+5:30 小时是正确的 - Asia/Kolkata ZoneId

正如评论中生动讨论的那样,建议使用 java.time 包。简单的解决方案:

Instant fourHoursAgo = Instant.now().minus(Duration.ofHours(4));
System.out.println(fourHoursAgo);

刚刚打印出来

2018-01-31T14:57:44.667255Z

由于 UTC 时间现在是 18:58,输出就是您所要求的。 Instant 本身是偏移中性的。它的 toString 提供 UTC 时间,但在生成 Instant 时没有提及 UTC,所以我不确定它是否能满足您的需求。稍后我会给你一个 显式 的结果 。

但首先,如果您确实需要 java.util.Date,通常对于您无法更改的遗留 API,转换很容易:

Date oldfashionedDate = Date.from(fourHoursAgo);
System.out.println(oldfashionedDate);

在我的 Europe/Copenhagen 时区的计算机上打印:

Wed Jan 31 15:57:44 CET 2018

同样,这与 运行 片段前四个小时的时间一致。同样,Date 中没有 UTC 偏移量。只有它的 toString 方法获取我的 JVM 的时区设置并使用它来生成字符串,这不会影响 Date。请参阅 Stack Overflow 问题 How to set time zone of a java.util.Date? 及其答案。

正如承诺的那样,如果您不仅需要表示时间还需要表示偏移量,请使用 OffsetDateTime:

OffsetDateTime fourHoursAgoInUtc = OffsetDateTime.now(ZoneOffset.UTC).minusHours(4);
System.out.println(fourHoursAgoInUtc);

此打印

2018-01-31T14:57:44.724147Z
末尾的

Z 表示与 UTC 或“祖鲁时区”(不是真正的时区)的偏移量为零。转换为 Date 并不比以前复杂多少,但是同样,您将在转换中丢失偏移量信息:

Date oldfashionedDate = Date.from(fourHoursAgoInUtc.toInstant());
System.out.println(oldfashionedDate);

这打印了:

Wed Jan 31 15:57:44 CET 2018

Link: Oracle tutorial explaining how to use java.time