Java即时到期 - 使用不同的时区

时间:2017-11-14 06:47:07

标签: java date

我在EST时区运行我的代码。

在我的代码中使用Instant.now(),它以UTC格式返回时间。

但是,我正在尝试测试一种从DB获取数据的方法,因为日期不是即时的,因此尝试使用

将其转换为日期
Date.from(Instant.now())

因为,我在美国东部时间运行这个,Date给了我在EST的时间。

实际代码,

    final Optional<Date> dbTime = dbService.getUpdatedTime();
    final Instant lastInstant = dbTime.orElseGet(() -> Date.from(Instant.now())).toInstant();

测试代码,

final Date dbTime = Date.from(Instant.now().minusSeconds(36000));
when(dbService.getUpdatedTime().thenReturn(Optional.of(dbTime));

此处,dbTime转换为EST时间。我可以通过设置TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

来恢复UTC时间

还有其他更好的方法吗?可以在主Application类中设置TimeZone.setDefault(TimeZone.getTimeZone("UTC"));,以便始终将其视为UTC吗?

1 个答案:

答案 0 :(得分:2)

首先建议,因为您可以使用现代Java日期和时间API,尽可能多地使用它,并尽量减少使用过时的Date类。如果您可以修改getUpdatedTime()以返回Optional<Instant>而不是Optional<Date>(现代JDBC驱动程序可以直接将数据库的日期时间作为Instant提供给您,那么将是最好的。 。由于Instant以UTC格式打印,因此应该删除所有问题和问题。

在这个答案中,我假设你要么不能做,要么就是不想做。不过你仍然可以接近:

    final Optional<Instant> dbTime = dbService.getUpdatedTime().map(Date::toInstant);
    final Instant lastReconInstant = dbTime.orElseGet(Instant::now);

避免使用TimeZone.setDefault()。由于JVM只有一个全局时区设置,因此可能会无意中更改程序其他部分或在同一JVM中运行的其他程序的行为。

详细信息,在您的存根代码中我建议您明确表示减去10小时。

有两种选择
    final Date dbTime = Date.from(Instant.now().minus(10, ChronoUnit.HOURS));

    final Date dbTime = Date.from(Instant.now().minus(Duration.ofHours(10)));

所有这些都说,在我看来,你首先没有问题。 Date中没有时区。它的toString方法只是抓取JVM的默认时区,并使用它来渲染日期和时间。这已经欺骗了许多人,这只是你可以避免这门课程的原因之一。