Getting Duration using the new dateTime API

2019-04-22 20:30发布

问题:

I want to get a java.time.Duration instance representing the duration of 3 years,
and i found 2 ways to do it (see code below).

public static void main(String[] args) {
    Duration d1 = Duration.of(3, ChronoUnit.YEARS); //Runtime Exception
    Duration d2 = ChronoUnit.YEARS.getDuration().multipliedBy(3);

    System.out.println("d2="+d2.toDays()); //OUTPUT: d2=1095
}

The first way, d1, throws the following Exception at runtime:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated duration
    at java.time.Duration.plus(Unknown Source)
    at java.time.Duration.of(Unknown Source)
    at mod7.vehicalc.Test.main(Test.java:26)

The second way, d2, works as expected.

What is the reason for this difference?

回答1:

A Duration is a time-based amount of time.

A Period is a date-based amount of time.

Given that years are clearly date-based and not time-based, you need to be using Period. (There is no "recurrance" aspect to Period).

Period p = Period.ofYears(3);

The estimated duration method on ChronoUnit is primarily intended for the purpose of sorting units, ie. being able to say that a year is generally longer than a month. It is not intended to be the basis of mathematical calculations or creating a larger Duration. In particular, if you use a Period then addition to a LocalDate or ZonedDateTime will result in the correct answer. If you use a Duration then you will probably get an unexpected/wrong answer.



回答2:

What is the reason for this difference?

The javadoc for ChronoUnit#getDuration() states

Gets the estimated duration of this unit in the ISO calendar system.

That is, YEARS is a

Unit that represents the concept of a year. For the ISO calendar system, it is equal to 12 months. The estimated duration of a year is 365.2425 Days.

or 31556952 seconds. This is just an estimation.

Duration.of(..) expects a unit with an exact time value.

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.