【发布时间】:2017-04-28 15:15:54
【问题描述】:
我不确定我是否了解 Java Period 和 Duration 之间的微妙之处。
当我阅读 Oracle 的 explanation 时,它说我可以找出这样的生日有多少天(使用他们使用的示例日期):
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
Period birthdayPeriod = Period.between(birthday, today);
int daysOld = birthdayPeriod.getDays();
但正如他们所指出的,这并没有考虑到你出生的时区和你现在所在的时区。但这是一台计算机,我们可以精确,对吧?那么我会使用Duration吗?
ZoneId bornIn = ZoneId.of("America/New_York");
ZonedDateTime born = ZonedDateTime.of(1960, Month.JANUARY.getValue(), 1, 2, 34, 56, 0, bornIn);
ZonedDateTime now = ZonedDateTime.now();
Duration duration = Duration.between(born, now);
long daysPassed = duration.toDays();
现在实际时间是准确的,但如果我理解正确,这些天可能无法正确代表日历日,例如与 DST 等。
那么我该怎么做才能根据我的时区获得准确的答案?我唯一能想到的就是回到使用LocalDate,但首先从ZonedDateTime 值规范化时区,然后使用Duration。
ZoneId bornIn = ZoneId.of("America/New_York");
ZonedDateTime born = ZonedDateTime.of(1960, Month.JANUARY.getValue(), 1, 2, 34, 56, 0, bornIn);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime nowNormalized=now.withZoneSameInstant(born.getZone());
Period preciseBirthdayPeriod = Period.between(born.toLocalDate(), nowNormalized.toLocalDate());
int preciseDaysOld = preciseBirthdayPeriod.getDays();
但这似乎真的很复杂,只是为了得到一个准确的答案。
【问题讨论】:
-
您所说的“准确答案”到底是什么意思?假设您在两天前的凌晨 12:30 出生,但昨天有一个 DST 转换,所以这一天有 25 个小时,现在是凌晨 12:30。你已经活了 2 个日历日,但是 49 小时。那时你想要什么“精确”的答案?如果您可以准确地指定您期望的答案,那么计算它应该不会太难......但您确实需要非常具体。 (这甚至没有考虑不同的区域。)另外,请使用预览确保您的代码在发布时格式正确。
-
期间是日历日之间的跨度,与一天中的时间无关。如果您想要比这更高的精度,则不应使用 Period。