Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
147 views
in Technique[技术] by (71.8m points)

Why can't I get a duration in minutes or hours in java.time?

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

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));

This raises an 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 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

"Why was it implemented that way?"

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

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.

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.

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.

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).

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

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.

New to…Part methods in 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
  • toNanosPart

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...