java-time - 时间单位的持续时间

标签 java-time

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

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

最佳答案

我不确定您是在谈论新的 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 中限制为纳秒)。如果您确实需要这种精度,可以很容易地增强示例。

关于java-time - 时间单位的持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29032923/

相关文章:

java - 在 Duration 步骤中迭代 ZonedDateTime 间隔

java - 使用 DateTimeFormatter 为 "early"日期格式化时间戳

java - 解析 ISO_INSTANT 和类似的日期时间字符串

java - 使用 Java 8 DateTimeFormatter 将字符串转换为 LocalDateTime

java - 如何使用DateTimeFormatter在java8中处理yyyy-mm和yyyy

Java:如何从 LocalTime 对象获取总分钟数

java - 如何使用java时间通过从语言标签获得的任何区域设置来格式化日期?

java - 以秒为单位获取当前时间

java-time - 如何解析带日期的字符串,但没有本地格式的时间到 ZonedDateTime?

java - 如何使用 Java 8 时间 API 将两位数年份转换为完整年份