有没有一种直接的方法可以将 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
的组合。您可以看看这是否适合您的目的。
链接:
- TheeTen Extra
- ThreeTen Extra 的文档
PeriodDuration
我知道 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
的组合。您可以看看这是否适合您的目的。
链接:
- TheeTen Extra
- ThreeTen Extra 的文档
PeriodDuration