为什么我不能在 java.time 中获得以分钟或小时为单位的持续时间? [英] Why can't I get a duration in minutes or hours in java.time?

查看:21
本文介绍了为什么我不能在 java.time 中获得以分钟或小时为单位的持续时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Of the Duration class in the new JSR 310 date API (java.time package) available in Java 8 and later, the javadoc says :

这个类以秒和纳秒.可以使用其他基于持续时间的单位访问它,例如作为分钟和小时.此外,可以使用 DAYS 单位并将其视为完全等于 24 小时,从而忽略夏令时效应.

This class models a quantity or amount of time in terms of seconds and nanoseconds. It can be accessed using other duration-based units, such as minutes and hours.In addition, the DAYS unit can be used and is treated as exactly equal to 24 hours, thus ignoring daylight savings effects.

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

So, why does the following code crash ?

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)

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

So what is the recommended way to extract minutes and hours from a duration object ? Do we have to make the calculation ourselves from the number of seconds ? Why was it implemented that way ?

推荐答案

为什么要这样实现?"

其他答案涉及允许查询小时/分钟的 toXxx() 方法.我会尽力解决原因.

Other answers deal with the toXxx() methods that allow the hours/minutes to be queried. I'll try to deal with the why.

TemporalAmount 接口和 get(TemporalUnit) 方法是在过程中较晚添加的.我个人并不完全相信我们有足够的证据证明在该领域的设计是正确的,但我有点不情愿地添加了 TemporalAmount.我相信这样做会让 API 有点混乱.

The TemporalAmount interface and get(TemporalUnit) method was added fairly late in the process. I personally was not entirely convinced that we had enough evidence of the right way to work the design in that area, but was slightly arm-twisted to add TemporalAmount. I believe that in doing so we slightly confused the API.

事后看来,我相信 TemporalAmount 包含正确的方法,但我相信 get(TemporalUnit) 应该有一个不同的方法名称.原因是 get(TemporalUnit) 本质上是一种框架级方法 - 它不是为日常使用而设计的.不幸的是,方法名称 get 并没有暗示这一点,导致在 Duration 上调用 get(ChronoUnit.MINUTES) 等错误.

In hindsight, I believe that TemporalAmount contains the right methods, but I believe that get(TemporalUnit) should have had a different method name. The reason is that get(TemporalUnit) is essentially a framework-level method - it is not designed for day-today use. Unfortunately the method name get does not imply this, resulting in bugs like calling get(ChronoUnit.MINUTES) on Duration.

因此,思考 get(TemporalUnit) 的方式是想象一个将数量视为 Map 的低级框架,其中 Duration 是大小为 2 的 Map,键为 SECONDSNANOS.

So, the way to think of get(TemporalUnit) is to imagine a low-level framework viewing the amount as a Map<TemporalUnit, Long> where Duration is a Map of size two with keys of SECONDS and NANOS.

同样地,Period 从低级框架看是一个 Map 大小为 3 - DAYS, >MONTHSYEARS(幸运的是出错的可能性较小).

In the same, way, Period is viewed from the low-level frameworks as a Map of size three - DAYS, MONTHS and YEARS (which fortunately has less chance of errors).

总的来说,应用程序代码的最佳建议是忽略方法 get(TemporalUnit).改用 getSeconds()getNano()toHours()toMinutes().

Overall, the best advice for application code is to ignore the method get(TemporalUnit). Use getSeconds(), getNano(), toHours() and toMinutes() instead.

最后,从 Duration 获取hh:mm:ss"的一种方法是:

Finally, one way to get "hh:mm:ss" from a Duration is to do:

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

一点也不漂亮,但它的持续时间不超过一天.

Not pretty at all, but it does work for durations less than one day.

JDK-8142936 问题现已在 Java 9 中实现,添加以下方法来访问每个部分持续时间.

JDK-8142936 issue now implemented in Java 9, adding the following methods to access each part of a Duration.

  • toDaysPart
  • toHoursPart
  • toMinutesPart
  • toSecondsPart
  • toMillisPart
  • 到NanosPart

这篇关于为什么我不能在 java.time 中获得以分钟或小时为单位的持续时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆