为什么 TimeUnit 计算如此不正确?
其他答案是正确的:您正在执行与您想要的相反的转换。TimeUnit.MILLISECONDS.convert(difference, TimeUnit.DAYS);
从天转换为毫秒。
但是你怎么得到一个负数?这是因为int
溢出。相反的转换正确执行并产生 434 758 135 795 200 000。这比 32 位int
可以容纳的要大得多。因此,当您转换为 时int
,最高有效位被切掉。偶然地,最终成为符号位的位int
是 1,表示负数。我通常会避免在没有先进行范围检查的情况下进行这种转换。你可能想养成同样的习惯。Math.toIntExact()
在这里很有帮助。
如何修复:java.time
其他答案基本还是正确的。我仍然想提供一些建议。
如果您认为从一天 16:04 到第二天 16:04 的时间是 1 天,那么您需要考虑时区才能得到正确的结果。例如:
ZoneId zone = ZoneId.of("Africa/Mogadishu");
ZonedDateTime birth = Instant.ofEpochMilli(ts).atZone(zone);
long ageInDays = ChronoUnit.DAYS.between(birth, ZonedDateTime.now(zone));
System.out.println(ageInDays);
在这种情况下,刚才运行代码的结果也是你所期望的:
58
另一方面,如果您将 1 天定义为 24 小时,无论挂钟的读数如何,这是一种以亚秒精度获取年龄的方法。您可以随时转换为之后的几天。
Instant birth = Instant.ofEpochMilli(ts);
Duration age = Duration.between(birth, Instant.now());
System.out.println(age);
System.out.println(age.toDays());
输出:
PT1398H52M13.994841S
58
两行中的第一行表示年龄是 1398 小时 52 分 13.994841 秒。第二行与之前的结果一致。
这两个片段背后的想法也可以组合和混合。总而言之,我认为这java.time
提供了一些更难获得的可能性TimeUnit
,以及一些非常清晰且不言自明的代码,您不会轻易犯与问题中相同的错误。
链接: