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

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

我已经回顾了截至4小时前的Stack Overflow问题获取日期及其答案。 但是我想避免添加更多的依赖项,比如jodaTime ,并且接受的答案使用System.currentTimeMillis()这将是本地时区,不是吗?

正如在评论中生动地讨论的那样,建议使用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 toString提供时间,但是在制作Instant时没有提到UTC,所以不管它给你你想要什么,我都不确定。 我稍后会给你一个明确在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问题, 如何设置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 

链接: Oracle教程解释如何使用java.time

您可以使用java.time包实现此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小时正确 – Asia/Kolkata ZoneId