期间两个ZonedDateTime之间的差异

时间:2017-04-21 23:23:26

标签: date java-8 java-time period

使用LocalDate,我得到了Period实例中表达的差异。例如:

ZonedDateTime now = ZonedDateTime.now(); // US/Pacific

LocalDate date = LocalDate.of(1990, Month.SEPTEMBER, 30);
LocalTime time = LocalTime.of(23, 55);
ZoneId zone = ZoneId.of("Australia/Melbourne");
ZonedDateTime born = ZonedDateTime.of(date, time, zone);

输出:

  

我的年龄是:26岁6个月23天

所以,我用时间来计算年,月,日的年龄。

我想使用两个时区(美国/太平洋和澳大利亚/墨尔本)对ZoneDateTime做同样的事情。例如:

{{1}}

我希望获得与LocalDate相同的输出。我该怎么办?它有意义吗?

预期产出:

  

我的年龄是:26岁6个月24天

3 个答案:

答案 0 :(得分:3)

我建议不要将ZonedDateTime用于出生日期,而是建议存储LocalDateZoneId(即在单独的字段/列中)。

从两个Period实例获取LocalDate的简单答案是在两者上调用toLocalDate()。正如您将意识到的那样,存在这些ZonedDateTime实例可能位于不同时区的问题,这可能需要工作才能进行规范化。但同样,我要强调的是,此数据的更好存储空间是两个字段 - LocalDateZoneId

Period p = Period.between(born.toLocalDate(), now.toLocalDate());
// warning! the above ignores time-zones, assuming both are the same

如果您需要Period加上Duration的两者之间的差异(剩余的秒数),您可以使用:

Period p = Period.between(born.toLocalDate(), now.toLocalDate());
Duration d = Duration.between(born.with(now.toLocalDate()), now);

最后一个选项是使用ThreeTen-Extra。即将发布的v1.1将包含一个PeriodDuration类,它结合了PeriodDuration,并允许存储两个LocalDateTime个实例之间的时间量。

答案 1 :(得分:2)

Period文档的第一行声明它是基于日期的ISO-8601格式的时间量。它并不适用于XXXTime。

但是,ZonedDateTime为您提供until方法,该方法会返回给定ChronoUnit的号码,直到另一个Temporal(您的情况为now)。

例如:

born.until(now, ChronoUnit.YEARS);

将返回26。

一个技巧是将检索到的差异添加到开始日期,然后处理下一个ChronoUnit

例如:

long years = born.until(now, ChronoUnit.YEARS);
born = born.plusYears(years);

long months = born.until(now, ChronoUnit.MONTHS);
born = born.plusMonths(months);

long days = born.until(now, ChronoUnit.DAYS);

然后你可以打印你的变量。

答案 2 :(得分:0)

你应该使用LocalDate表示生日的主要原因是因为每个人都以同样的方式观察他们的生日,或换句话说,每个人都会根据他们在哪里观察他们的生日目前在。如果你出生在法国,现在住在美国有不同的时区偏移,你不会通过观察法国的当前日期来庆祝你的生日,你会检查你当前的日期本地给你。具有时区支持的时间类应该用于跨越区域的事件,例如,航班到达和离开跟踪软件。因此,使用ZonedDateTime来描述生日并没有错,它在语义上是不正确的。

此外,Period实现了TemporalAmount,这显然代表了一段时间。所以用它来代表生日是(再次)没错,但它会让你的意图不那么清楚。生日是时间轴上的确切时刻,而不是持续时间,所以总而言之,LocalDate是最佳选择