如何在过去的特定时间使用 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
是否可以创建一个 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