首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将time4j Duration<IsoUnit>从P365D转换为P1Y等

将time4j Duration<IsoUnit>从P365D转换为P1Y等
EN

Stack Overflow用户
提问于 2019-05-21 14:48:39
回答 2查看 431关注 0票数 1
代码语言:javascript
复制
Instant i1 = Instant.now();
Instant i2 = Instant.now().plusSeconds(60 * 60 * 24 * 365);
Duration<IsoUnit> dur = Duration.from((TemporalAmount) java.time.Duration.between(i1, i2));
System.out.println(dur);

这段代码打印P365D,有没有办法让单元填满下一个更大的单元,这样就变成了P1Y,如果我有P334D到P11M之类的东西的话?

time4j版本为4.38

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-22 05:19:18

其他评论和回答完全正确地说,一年并不总是等于365天。

Time4J-方法net.time4j.Duration.from(TemporalAmount)使用STD_PERIOD作为规范化器返回规范化持续时间。这个规范化器的文档说:

根据1年=12个月和1天= 24小时和1小时= 60分钟1分钟=60秒的基准将持续时间项目正常化,但不将天数转换为月份。

因此,您只能期望在以秒为单位定义的时间数量开始的几天内得到结果。

如果您还想要一年,那么我建议您首先使用适当的时区将即时日期转换为日历日期。但是在闰年,您的代码仍然会产生365天,而不是在将60 * 60 * 24 * 365秒添加到第二个瞬间之后一年。所以你增加的秒也是有缺陷的,因为它是基于错误的假设。

附带说明:

如果您希望采用相反的方式,即一年中有多少秒,那么您可以使用以下代码

代码语言:javascript
复制
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,并考虑以下映射:

代码语言:javascript
复制
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 (或更高版本)的另一种方法可以通过“模糊”持续时间来实现。您可以通过应用近似来规范所获得的持续时间。示例:

代码语言:javascript
复制
    Duration<IsoUnit> d = Duration.of(60 * 60 * 24 * 365, ClockUnit.SECONDS);
    d = d.with(Duration.approximateMaxUnitOnly());
    System.out.println(d); // P1Y

由于这种规范化的性质,您不能期望得到确切的结果。

票数 2
EN

Stack Overflow用户

发布于 2019-05-21 15:31:03

一年没有固定的秒数:

  1. 闰年在2月29日有额外的一天。
  2. 有时会添加闰秒

由于以上原因,你必须知道一年中有多少秒。与InstantDuration不同,您应该使用LocalDatePeriod (至少在使用java.time时):

代码语言:javascript
复制
LocalDate d1 = LocalDate.now();
LocalDate d2 = d1.plusYears(1);
Period p = Period.between(d1, d2);
System.out.println(p); // P1Y
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56240919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档