Getting Duration using the new dateTime API

2019-04-22 20:42发布

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?

2条回答
迷人小祖宗
2楼-- · 2019-04-22 21:11

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.

查看更多
Animai°情兽
3楼-- · 2019-04-22 21:33

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.

查看更多
登录 后发表回答