其他评论和答案完全正确地说一年并不总是等于365天。
Time4J 方法net.time4j.Duration.from(TemporalAmount)使用规范化器返回规范化的持续时间STD_PERIOD
。这个规范器的文档说:
在 1 年 = 12 个月和 1 天 = 24 小时和 1 小时 = 60 分钟和 1 分钟 = 60 秒的基础上标准化持续时间项目 - 无需将天转换为月。
因此,当您以以秒为单位的时间量开始时,您只能期望结果以天为单位。
如果您仍然想要一年,那么我建议您首先使用适当的时区将您的瞬间转换为日历日期。但是在闰年,你的代码60 * 60 * 24 * 365
在第二个瞬间增加秒后仍然会产生 365 天而不是一年。因此,您添加秒数也是有缺陷的,因为它基于错误的假设。
边注:
如果你想要相反的方式,即一年中有多少秒,那么你可以使用类似的代码
Moment m1 = Moment.nowInSystemTime();
Moment m2 = m1.toZonalTimestamp(ZonalOffset.UTC).plus(1, CalendarUnit.YEARS).atUTC();
long seconds = SI.SECONDS.between(m1, m2); // = 366 days in seconds if applied on date 2019-05-22!
随着 Time4J 的未来版本和 2019 年底可能的闰秒,代码甚至可能产生额外的一秒。
无论如何,我建议您将 Time4J 更新到 v5.4 并考虑以下映射:
java.time.Instant as input => net.time4j.MachineTime.from(...)
java.time.LocalDateTime/net.time4j.PlainTimestamp => net.time4j.Duration.from(...)
因此,如果您真的希望在打印持续时间中尽可能输出几年并且您有瞬间/时刻,那么在创建适当的持续时间对象之前首先转换为 LocalDateTime/PlainTimestamp(使用时区或偏移量)。
2019-05-25 更新:
v5.4(或更高版本)版本的另一种方法是通过“模糊”持续时间。您可以通过应用近似值来标准化获得的持续时间。例子:
Duration<IsoUnit> d = Duration.of(60 * 60 * 24 * 365, ClockUnit.SECONDS);
d = d.with(Duration.approximateMaxUnitOnly());
System.out.println(d); // P1Y
由于这种归一化的性质,您不能期望得到准确的结果。