Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Instant does not support operations with ChronoUnit.YEARS?

This was unexpected to me:

> Clock clock = Clock.systemUTC();  > Instant.now(clock).minus(3, ChronoUnit.DAYS); java.time.Instant res4 = 2016-10-04T00:57:20.840Z  > Instant.now(clock).minus(3, ChronoUnit.YEARS); java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Years 

As a workaround I have to do this:

> Instant.now(clock).atOffset(ZoneOffset.UTC).minus(3, ChronoUnit.YEARS).toInstant(); java.time.Instant res11 = 2013-10-07T01:02:56.361Z 

I am curios why Instant does not support YEARS. Did developers just give up on it?

(In my actual code I tried to subtract a Period.ofYears(3) but the quoted Instant methods are the ones being called in the end).

like image 851
alexandroid Avatar asked Oct 07 '16 01:10

alexandroid


People also ask

What is Temporal interface?

The Temporal interface simulates a common concept between the concepts of date, time and time-offset. It provides basic methods to get information from these objects. public interface Temporal extends TemporalAccessor.

What is Temporal class in java?

Java For Testers A temporal field is a field of date-time, such as month-of-year or hour-of-minute. These fields are represented by the TemporalField interface and the ChronoField class implements this interface.

How do you add instant days?

Instant plus() method in Java An immutable copy of a instant where a time unit is added to it can be obtained using the plus() method in the Instant class in Java. This method requires two parameters i.e. time to be added to the instant and the unit in which it is to be added.


1 Answers

I'm taking a stab at it in what looks to me like something very logical.

Here is the code for the method plus(long, TemporalUnit) (which is used in minus(...)):

@Override public Instant plus(long amountToAdd, TemporalUnit unit) {     if (unit instanceof ChronoUnit) {         switch ((ChronoUnit) unit) {             case NANOS: return plusNanos(amountToAdd);             case MICROS: return plus(amountToAdd / 1000_000, (amountToAdd % 1000_000) * 1000);             case MILLIS: return plusMillis(amountToAdd);             case SECONDS: return plusSeconds(amountToAdd);             case MINUTES: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_MINUTE));             case HOURS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_HOUR));             case HALF_DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY / 2));             case DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY));         }         throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);     }     return unit.addTo(this, amountToAdd); } 

We can see that the results are calculated by multiplying seconds representation of units, a year cannot be logically and consistently represented by seconds for obvious reasons.


Addition

I can see another obvious reason why : constants used in the method above come from java.time.LocalTime. The constants only define units up to days. No constant above days are defined (in LocalDate and LocalDateTime neither).

like image 88
Yassin Hajaj Avatar answered Oct 12 '22 21:10

Yassin Hajaj