/// <summary> /// Converts this {@code FileTime} object to an {@code Instant}. /// /// <para> The conversion creates an {@code Instant} that represents the /// same point on the time-line as this {@code FileTime}. /// /// </para> /// <para> {@code FileTime} can store points on the time-line further in the /// future and further in the past than {@code Instant}. Conversion /// from such further time points saturates to <seealso cref="Instant#MIN"/> if /// earlier than {@code Instant.MIN} or <seealso cref="Instant#MAX"/> if later /// than {@code Instant.MAX}. /// /// </para> /// </summary> /// <returns> an instant representing the same point on the time-line as /// this {@code FileTime} object /// @since 1.8 </returns> public Instant ToInstant() { if (Instant == null) { long secs = 0L; int nanos = 0; switch (Unit.InnerEnumValue()) { case TimeUnit.InnerEnum.DAYS: secs = Scale(Value, SECONDS_PER_DAY, Long.MaxValue / SECONDS_PER_DAY); break; case TimeUnit.InnerEnum.HOURS: secs = Scale(Value, SECONDS_PER_HOUR, Long.MaxValue / SECONDS_PER_HOUR); break; case TimeUnit.InnerEnum.MINUTES: secs = Scale(Value, SECONDS_PER_MINUTE, Long.MaxValue / SECONDS_PER_MINUTE); break; case TimeUnit.InnerEnum.SECONDS: secs = Value; break; case TimeUnit.InnerEnum.MILLISECONDS: secs = Math.FloorDiv(Value, MILLIS_PER_SECOND); nanos = (int)Math.FloorMod(Value, MILLIS_PER_SECOND) * NANOS_PER_MILLI; break; case TimeUnit.InnerEnum.MICROSECONDS: secs = Math.FloorDiv(Value, MICROS_PER_SECOND); nanos = (int)Math.FloorMod(Value, MICROS_PER_SECOND) * NANOS_PER_MICRO; break; case TimeUnit.InnerEnum.NANOSECONDS: secs = Math.FloorDiv(Value, NANOS_PER_SECOND); nanos = (int)Math.FloorMod(Value, NANOS_PER_SECOND); break; default: throw new AssertionError("Unit not handled"); } if (secs <= MIN_SECOND) { Instant = Instant.MIN; } else if (secs >= MAX_SECOND) { Instant = Instant.MAX; } else { Instant = Instant.OfEpochSecond(secs, nanos); } } return(Instant); }