为什么在 java.time 中无法以分钟或小时为单位获得持续时间?Java 9 中的新方法to…Part

2022-08-31 12:22:08

在 Java 8 及更高版本中可用的新 JSR 310 日期 API(java.time 包)中的 Duration 类中,javadoc 说:

此类以秒和纳秒为单位对时间量或量进行建模。可以使用其他基于持续时间的单位(如分钟和小时)访问它。此外,可以使用 DAYS 单位,并被视为完全等于 24 小时,从而忽略夏令时效应。

那么,为什么以下代码会崩溃?

Duration duration = Duration.ofSeconds(3000);
System.out.println(duration.get(ChronoUnit.MINUTES));

这引发了一个:UnsupportedTemporalTypeException

java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Minutes
    at java.time.Duration.get(Duration.java:537)

那么,从持续时间对象中提取分钟和小时的建议方法是什么?我们是否必须根据秒数自己进行计算?为什么以这种方式实现?


答案 1

“为什么以这种方式实现它?”

其他答案处理允许查询小时/分钟的方法。我会试着处理为什么。toXxx()

接口和方法在流程的后期添加。我个人并不完全相信我们有足够的证据证明在该领域进行设计的正确方法,但是稍微有点扭曲了。我相信这样做会稍微混淆API。TemporalAmountget(TemporalUnit)TemporalAmount

事后看来,我相信它包含正确的方法,但我相信应该有一个不同的方法名称。原因是这本质上是一种框架级方法 - 它不是为今天使用而设计的。不幸的是,方法名称并不意味着这一点,导致诸如调用.TemporalAmountget(TemporalUnit)get(TemporalUnit)getget(ChronoUnit.MINUTES)Duration

因此,思考的方法是想象一个低级框架将数量视为一个大小为二的,键为和。get(TemporalUnit)Map<TemporalUnit, Long>DurationMapSECONDSNANOS

同样,从低级框架中可以将其视为大小为三 - 和(幸运的是,出错的可能性较小)。PeriodMapDAYSMONTHSYEARS

总体而言,应用程序代码的最佳建议是 忽略该方法 。请改用 、 和 。get(TemporalUnit)getSeconds()getNano()toHours()toMinutes()

最后,从中获取“hh:mm:ss”的一种方法是执行以下操作:Duration

LocalTime.MIDNIGHT.plus(duration).format(DateTimeFormatter.ofPattern("HH:mm:ss"))

一点也不漂亮,但它确实在不到一天的持续时间内有效。

Java 9 中的新方法to…Part

JDK-8142936 问题现在在 Java 9 中实现,添加了以下方法来访问 .Duration

  • toDaysPart
  • toHoursPart
  • toMinutesPart
  • toSecondsPart
  • toMillisPart
  • toNanosPart

答案 2

文档说:

这将返回两个受支持的单位(秒和 NANOS)中每个单位的值。所有其他单位都会引发异常。

所以,最好的猜测答案 - 这就是他们设计它的方式。

您可以使用其他一些方法在几小时内获得它:

long hours = duration.toHours();

分钟

long minutes = duration.toMinutes();

推荐