时间单位的持续时间

Duration to TemporalUnits

如何将持续时间转换为一组时间单位?我有一个持续时间,我想将其分为整年、整日和小数秒。

我找到了 PeriodFormatterBuilder 的 JodaTime,但它似乎便于打印和划分为单位,我只是喜欢划分。

我不确定你是在谈论 Java-8 的新 java.time-package 还是关于 Joda-Time,所以我尝试为这两个库提供解决方案。

然而,最重要的方面是您不能以自洽的方式将以秒定义的 Duration 划分为年、月等,因为基于月的单位在秒和天的长度上有所不同。至少没有任何技巧是不可能的。

在这种情况下,您可以做的最好的事情是使用参考时间戳来重新计算您拥有的持续时间。这意味着您 将持续时间添加到参考时间戳,然后计算旧参考时间戳与结果之间的新持续时间(以年、月、日等为单位) 这也称为 normalization 与 printing/formatting.

无关

Java-8:

Duration dur = Duration.ofSeconds(5000001); // example
LocalDateTime ref = LocalDateTime.now(); // reference timestamp
LocalDateTime end = ref.plus(dur);

System.out.println(ref);
System.out.println(end);

// normalize first the calendrical part
LocalDateTime ldt = ref;
long years = ChronoUnit.YEARS.between(ldt, end);

// find the months part
ldt = ldt.plus(years, ChronoUnit.YEARS);
long months = ChronoUnit.MONTHS.between(ldt, end);

// find the days part
ldt = ldt.plus(months, ChronoUnit.MONTHS);
long days = ChronoUnit.DAYS.between(ldt, end);

// find the hours part
ldt = ldt.plus(days, ChronoUnit.DAYS);
long hours = ChronoUnit.HOURS.between(ldt, end);

// find the minutes part
ldt = ldt.plus(hours, ChronoUnit.HOURS);
long minutes = ChronoUnit.MINUTES.between(ldt, end);

// find the seconds part
ldt = ldt.plus(minutes, ChronoUnit.MINUTES);
long seconds = ChronoUnit.SECONDS.between(ldt, end);

// print the new normalized duration in ISO-8601-format
System.out.println(
  String.format("P%1$dY%2$dM%3$dDT%4$dH%5$dM%6$dS", years, months, days, hours, minutes, seconds));

// example output
// 2015-03-17T12:54:07.943
// 2015-05-14T09:47:28.943
// P0Y1M26DT20H53M21S

与旧的 JDK pre 8 相比,这可以被认为更好,因为至少提供了计算一个给定单元中持续时间的基本方法。但是完全缺少用于处理从年到秒的所有单位的通用持续时间类型。我能找到的最好的持续时间格式化程序就是 java.util.Formatter.

乔达时间

当需要持续时间处理时,这是第二好的 Java 库,在大多数细节上优于 Java-8 在这方面。 Joda-Time 确实提供了一种从年到秒(和毫秒)的持续时间类型,称为 Period。在这里查看更简单的解决方案:

Duration dur = new Duration(5000001 * 1000L); // in milliseconds
LocalDateTime ref = new LocalDateTime(); // reference timestamp
LocalDateTime end = ref.plus(dur);

// construct normalized duration
PeriodType type = PeriodType.yearMonthDayTime().withMillisRemoved();
Period p = new Period(ref, end, type);

// print the new normalized duration
System.out.println(p); // P1M26DT20H53M21S

小提示:在给定的示例中,我省略了小数秒(在 Joda-Time 中限制为毫秒,在 Java-8 中限制为纳秒)。如果您确实需要这种精度,可以很容易地增强示例。