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