diff --git a/src/main/java/org/apache/commons/lang3/time/Instants.java b/src/main/java/org/apache/commons/lang3/time/Instants.java index 8532afaf9fa..094cb431982 100644 --- a/src/main/java/org/apache/commons/lang3/time/Instants.java +++ b/src/main/java/org/apache/commons/lang3/time/Instants.java @@ -17,6 +17,7 @@ package org.apache.commons.lang3.time; +import java.time.Duration; import java.time.Instant; /** @@ -86,11 +87,13 @@ public static Instant toInstant(final Instant instant, final Instant defaultInst * @return long The duration in milliseconds since the given Instant. */ public static long toMillisSince(final Instant instant) { - final Instant instant2 = toInstant(instant); + // The sign of the duration is the opposite of the sign of the instant's epoch second: an instant far in the past + // yields a large positive duration, an instant far in the future a large negative one. Bind on the duration. + final Duration duration = DurationUtils.since(toInstant(instant)); try { - return DurationUtils.since(instant2).toMillis(); + return duration.toMillis(); } catch (final ArithmeticException e) { - return toBound(instant2, Long.MIN_VALUE, Long.MAX_VALUE); + return duration.isNegative() ? Long.MIN_VALUE : Long.MAX_VALUE; } } diff --git a/src/test/java/org/apache/commons/lang3/time/InstantsTest.java b/src/test/java/org/apache/commons/lang3/time/InstantsTest.java index 0a7bfdb9f47..1da2587478d 100644 --- a/src/test/java/org/apache/commons/lang3/time/InstantsTest.java +++ b/src/test/java/org/apache/commons/lang3/time/InstantsTest.java @@ -179,23 +179,21 @@ void testToMillisSinceFutureInstantIsNegative() { } /** - * {@link Instant#MAX} (positive epoch second): the huge negative duration from Instant.MAX to now - * overflows {@code long} millis; the bound is {@link Long#MAX_VALUE} because the instant's epoch - * second is positive. + * {@link Instant#MAX} is in the future, so the duration from it to now is negative and underflows {@code long} + * millis; the bound is {@link Long#MIN_VALUE}. */ @Test - void testToMillisSinceInstantMaxOverflowReturnsMaxValue() { - assertEquals(Long.MAX_VALUE, Instants.toMillisSince(Instant.MAX)); + void testToMillisSinceInstantMaxUnderflowReturnsMinValue() { + assertEquals(Long.MIN_VALUE, Instants.toMillisSince(Instant.MAX)); } /** - * {@link Instant#MIN} (negative epoch second): the huge positive duration from Instant.MIN to now - * overflows {@code long} millis; the bound is {@link Long#MIN_VALUE} because the instant's epoch - * second is negative. + * {@link Instant#MIN} is in the past, so the duration from it to now is positive and overflows {@code long} + * millis; the bound is {@link Long#MAX_VALUE}. */ @Test - void testToMillisSinceInstantMinOverflowReturnsMinValue() { - assertEquals(Long.MIN_VALUE, Instants.toMillisSince(Instant.MIN)); + void testToMillisSinceInstantMinOverflowReturnsMaxValue() { + assertEquals(Long.MAX_VALUE, Instants.toMillisSince(Instant.MIN)); } /**