TemporalUnits的持续时间

时间:2015-03-13 13:01:03

标签: java-time

如何将持续时间转换为一组时间单位?我有一个持续时间,我想把它分成例如整年,整天和小数秒。

我已经为JodaTime找到了PeriodFormatterBuilder,但它似乎有助于打印以及划分为单位,我只是喜欢这个部门。

1 个答案:

答案 0 :(得分:2)

我不确定您是否谈论新的java.time - Java-8包或Joda-Time,所以我尝试为两个库提供解决方案。

然而,最重要的方面是,您不能以自我一致的方式将以秒为单位定义的Duration分为年,月等,因为基于月份的单位的秒数和天数不同。至少在没有任何技巧的情况下是不可能的。

在这种情况下,您可以做的最好是使用参考时间戳来重新计算您的持续时间。这意味着您将您的持续时间添加到参考时间戳,然后评估旧参考时间戳与年,月,日等结果之间的新持续时间。这也称为规范化并且与打印/格式化无关。

的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中为几纳秒)。如果你真的需要这种精度,很容易增强这些例子。