Duration does not support DAYS contrary to class documentation
Asked Answered
S

3

8

In the java.time framework of Java 8 and later, the Duration class 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.

Yet when I call the get method and pass ChronoUnit.DAYS, an exception is thrown.

LocalTime start = LocalTime.of ( 0 , 0 , 0 ); // First moment of the day.
LocalTime stop = LocalTime.of ( 2 , 0 , 0 ); // 2 AM.

Duration duration = Duration.between ( start , stop );
long days = duration.get ( ChronoUnit.DAYS );

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Days

Am I misunderstanding something, or misusing the classes?

Seminar answered 2/2, 2016 at 23:7 Comment(3)
As far as I remember the only ChronoUnit constants that work in Duration.get(...) are SECONDS and NANOS but I never found out why.Fingerbreadth
@Fingerbreadth Why? It is because of the inner state of Duration which only holds seconds and nanoseconds. The get(TemporalField)-method is designed to yield a partial amount according to the inner state. In contrast, toDays() tries to determine the whole amount converted to days on base 1d=24h.Silvery
I have a typo in my previous comment. Instead of saying get(TemporalField) I wanted to say: get(TemporalUnit).Silvery
E
4

The get(TemporalUnit) method is unfortunately confusing and not intended for most users. To understand why, see this answer.

Java SE 9 will include a much richer set of access methods for Duration. For now, you can use toDays() to get the total number of days.

The Javadoc is not exactly wrong, but maybe not perfectly helpful. The class does have some support for days of 24 hours in the toDays(), ofDays(), plusDays() etc. It is just that the get(TemporalUnit) method is very misleadingly named (should be internalGet(TemporalUnit) or some such name).

Elysian answered 4/2, 2016 at 14:11 Comment(0)
T
6

Documentation for get on the Duration class.

Gets the value of the requested unit. This returns a value for each of the two supported units, SECONDS and NANOS. All other units throw an exception.

However, the Duration class has a method called toDays:

Gets the number of days in this duration. This returns the total number of days in the duration by dividing the number of seconds by 86400. This is based on the standard definition of a day as 24 hours.

Touchline answered 2/2, 2016 at 23:20 Comment(3)
So the class documentation is in error, and I should file a bug report?Seminar
@BasilBourque I don't think this is a bug, but maybe just slightly confusing documentation. The overall class description just gives a summary. I'd consider method descriptions to trump the overall summary. It doesn't explicitly say where you can use DAYS, but if you read some of the other methods (like minus) you can use DAYS in those cases.Touchline
I expended the doc quote. Sure seems to me that we should be able to get a number of days.Seminar
E
4

The get(TemporalUnit) method is unfortunately confusing and not intended for most users. To understand why, see this answer.

Java SE 9 will include a much richer set of access methods for Duration. For now, you can use toDays() to get the total number of days.

The Javadoc is not exactly wrong, but maybe not perfectly helpful. The class does have some support for days of 24 hours in the toDays(), ofDays(), plusDays() etc. It is just that the get(TemporalUnit) method is very misleadingly named (should be internalGet(TemporalUnit) or some such name).

Elysian answered 4/2, 2016 at 14:11 Comment(0)
T
0

A. It's better to replace

LocalTime start = LocalTime.of(0, 0, 0); // First moment of the day.

with

LocalTime start = LocalTime.MIN; // First moment of the day.

or with

LocalTime start = LocalTime.MIDNIGHT; // First moment of the day.

Also, the following

LocalTime stop = LocalTime.of ( 2 , 0 , 0 ); // 2 AM.

can be replaced with

LocalTime stop = LocalTime.of ( 2 , 0 ); // 2 AM.

B. The exception that you have encountered is the expected behaviour and is already documented at Duration:

This returns a value for each of the two supported units, SECONDS and NANOS. All other units throw an exception.

You can get the list of supported units using Duration#getUnits which unfortunately has been declared as a non-static function (and therefore you will have to create an arbitrary duration in order to use it):

import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        Duration duration = Duration.ofDays(10);// An arbitrary duration
        System.out.println(duration.getUnits());
    }
}

Output:

[Seconds, Nanos]
Tropous answered 29/12, 2020 at 17:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.