有没有一种直接的方法可以将 java.time.Period 转换为 java.time.Duration?

Is there a straightforward way to convert java.time.Period into java.time.Duration?

我知道 java.time.Period 是一个“估计值”,java.time.Duration 是准确的。我仍然想将 Period 转换为 Duration。或者至少在不诉诸技巧的情况下声明持续数周或更长时间。

即使编译成功,它也会抛出运行时异常,因为 ChronoUnit.WEEKS 和更大的 return 对于 ChronoUnit.isDurationEstimated()

为真
var d = Duration.of(2, ChronoUnit.WEEKS);

同样,这编译但抛出相同的原因:

var d = Duration.from(Period.ofWeeks(2));

从 ISO-8601 字符串进行往返有效,但味道不对:

var p = Period.ofWeeks(2);
var d = Duration.parse(p.toString());

有更好的方法吗?

没有直接的方法可以将 Period 转换为 Duration,因为您必须将年或月转换为日、分、秒、毫秒或纳秒。但是,1 年等于 365 或 366 天(闰年)?或者 1 个月等于 28、29、30 或 31 天?

不过,您可以估算一下。例如:

public static Duration ofPeriod(Period period) {

    long days = period.getDays() + Math.round((period.toTotalMonths() / 12d) * 365.2425d);

    return Duration.ofDays(days);
}

那么你可以这样做:

Period period = Period.ofWeeks(2);

Duration duration = ofPeriod(period);

System.out.println(duration);

输出:

PT336H

问题

一个java.time.Period是年、月、日的周期。 java.time.Duration 是小时、分钟、秒和秒的小数的持续时间。它们不兼容,一般来说,将一种转换为另一种是没有意义的。

我假设您仍然有尝试这样做的实际目的。其他人已经提到,您需要决定考虑一年和一个月的时间长度,因为它们的长度并不总是相同。天数也是如此:一天的长度也不总是一样的。诚然,通常是 24 小时,但也可能是 23 或 25 小时或其他长度。

顺便说一句,另一个区别是 Period 将各个字段保留数年、数月和数天。您可以 Period 2 年 28 个月零 -3 天。 Duration 不保留单独的字段,始终将 60 秒转换为一分钟,将 60 分钟转换为一小时。

A Period 接受周计数,但将一周转换为 7 天。 Duration 同样接受天数并将一天转换为 24 小时,而不考虑我刚才所说的事实,一天并不总是 24 小时。

所有这些都意味着您可以将 Period 天 and/or 周转换为 Duration,例如使用您的字符串方法,如果您接受一天的假设是 24 小时。如果 Period 中有任何年份或月份,您的方法将失败并出现异常。

没有四舍五入的解决方案

java.time 包括年和月的估计持续时间。这些可能适合也可能不适合您的目的。只有你能决定。我可以告诉你如何使用它们。

public static Duration ofPeriod(Period period) {
    Duration years = ChronoUnit.YEARS.getDuration().multipliedBy(period.getYears());
    Duration months = ChronoUnit.MONTHS.getDuration().multipliedBy(period.getMonths());
    Duration days = ChronoUnit.DAYS.getDuration().multipliedBy(period.getDays());
    return years.plus(months).plus(days);
}

在 2 周的例子中,问题给出了与另一个答案相同的结果:

PT336H

月份和年份的处理方式不同。让我们试试1年1个月:

    Period period = Period.of(1, 1, 0);
    Duration duration = ofPeriod(period);
    System.out.println(duration);

PT9496H18M18S

所以 9496 小时 18 分 18 秒。

额外三十分 PeriodDuration

ThreeTen Extra 项目与 java.time 一起开发,包括一个 PeriodDuration class 的时期或持续时间,年、月、日、小时、分钟、秒和一小部分第二。顾名思义,一个Period和一个Duration的组合。您可以看看这是否适合您的目的。

链接: