java - jdk - ¿Por qué Instant no admite operaciones con ChronoUnit.YEARS?
openjdk descargar (1)
Estoy probando lo que me parece algo muy lógico.
Aquí está el código para el método plus(long, TemporalUnit)
(que se usa en 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);
}
Podemos ver que los resultados se calculan multiplicando los segundos de representación de las unidades, un año no puede representarse de forma lógica y consistente por segundos por razones obvias.
Adición
Puedo ver otra razón obvia por la que: las constantes utilizadas en el método anterior provienen de java.time.LocalTime
. Las constantes solo definen unidades hasta días. No se definen días constantes anteriores (ni en LocalDateTime
ni en LocalDateTime
).
Esto fue inesperado para mí:
> 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
Como solución tengo que hacer esto:
> Instant.now(clock).atOffset(ZoneOffset.UTC).minus(3, ChronoUnit.YEARS).toInstant();
java.time.Instant res11 = 2013-10-07T01:02:56.361Z
Soy curioso por qué Instant no soporta AÑOS. ¿Los desarrolladores se dieron por vencidos?
(En mi código real intenté restar un Period.ofYears(3)
pero los métodos Instantáneos citados son los que se llaman al final).