diff --git a/jdk/src/java.base/share/classes/java/time/Duration.java b/jdk/src/java.base/share/classes/java/time/Duration.java index b7060a91ef4..334bfa0227a 100644 --- a/jdk/src/java.base/share/classes/java/time/Duration.java +++ b/jdk/src/java.base/share/classes/java/time/Duration.java @@ -996,6 +996,24 @@ public final class Duration return create(toBigDecimalSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN)); } + /** + * Returns number of whole times a specified Duration occurs within this Duration. + *

+ * This instance is immutable and unaffected by this method call. + * + * @param divisor the value to divide the duration by, positive or negative, not null + * @return number of whole times, rounded toward zero, a specified + * {@code Duration} occurs within this Duration, may be negative + * @throws ArithmeticException if the divisor is zero, or if numeric overflow occurs + * @since 9 + */ + public long dividedBy(Duration divisor) { + Objects.requireNonNull(divisor, "divisor"); + BigDecimal dividendBigD = toBigDecimalSeconds(); + BigDecimal divisorBigD = divisor.toBigDecimalSeconds(); + return dividendBigD.divideToIntegralValue(divisorBigD).longValueExact(); + } + /** * Converts this duration to the total length in seconds and * fractional nanoseconds expressed as a {@code BigDecimal}. diff --git a/jdk/test/java/time/tck/java/time/TCKDuration.java b/jdk/test/java/time/tck/java/time/TCKDuration.java index 7f70916ac95..1ef1302c6ff 100644 --- a/jdk/test/java/time/tck/java/time/TCKDuration.java +++ b/jdk/test/java/time/tck/java/time/TCKDuration.java @@ -2392,6 +2392,65 @@ public class TCKDuration extends AbstractTCKTest { assertEquals(test.dividedBy(Long.MAX_VALUE), Duration.ofSeconds(1)); } + //----------------------------------------------------------------------- + // dividedbyDur() + //----------------------------------------------------------------------- + + @DataProvider(name="dividedByDur_provider") + Object[][] provider_dividedByDur() { + return new Object[][] { + {Duration.ofSeconds(0, 0), Duration.ofSeconds(1, 0), 0}, + {Duration.ofSeconds(1, 0), Duration.ofSeconds(1, 0), 1}, + {Duration.ofSeconds(6, 0), Duration.ofSeconds(3, 0), 2}, + {Duration.ofSeconds(3, 0), Duration.ofSeconds(6, 0), 0}, + {Duration.ofSeconds(7, 0), Duration.ofSeconds(3, 0), 2}, + + {Duration.ofSeconds(0, 333_333_333), Duration.ofSeconds(0, 333_333_333), 1}, + {Duration.ofSeconds(0, 666_666_666), Duration.ofSeconds(0, 333_333_333), 2}, + {Duration.ofSeconds(0, 333_333_333), Duration.ofSeconds(0, 666_666_666), 0}, + {Duration.ofSeconds(0, 777_777_777), Duration.ofSeconds(0, 333_333_333), 2}, + + {Duration.ofSeconds(-7, 0), Duration.ofSeconds(3, 0), -2}, + {Duration.ofSeconds(0, 7), Duration.ofSeconds(0, -3), -2}, + {Duration.ofSeconds(0, -777_777_777), Duration.ofSeconds(0, 333_333_333), -2}, + + {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), 29}, + {Duration.ofSeconds(-432000L, 777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), -29}, + {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), -29}, + {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(14400L, -333_333_333L), -30}, + {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(-14400L, 333_333_333L), -30}, + {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(-14400L, -333_333_333L), -29}, + {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(-14400L, -333_333_333L), 29}, + + {Duration.ofSeconds(Long.MAX_VALUE, 0), Duration.ofSeconds(1, 0), Long.MAX_VALUE}, + {Duration.ofSeconds(Long.MAX_VALUE, 0), Duration.ofSeconds(Long.MAX_VALUE, 0), 1}, + }; + } + + @Test(dataProvider="dividedByDur_provider") + public void test_dividedByDur(Duration dividend, Duration divisor, long expected) { + assertEquals(dividend.dividedBy(divisor), expected); + } + + @Test(expectedExceptions=ArithmeticException.class) + public void test_dividedByDur_zero() { + Duration t = Duration.ofSeconds(1, 0); + t.dividedBy(Duration.ZERO); + } + + @Test(expectedExceptions=NullPointerException.class) + public void test_dividedByDur_null() { + Duration t = Duration.ofSeconds(1, 0); + t.dividedBy(null); + } + + @Test(expectedExceptions=ArithmeticException.class) + public void test_dividedByDur_overflow() { + Duration dur1 = Duration.ofSeconds(Long.MAX_VALUE, 0); + Duration dur2 = Duration.ofNanos(1); + dur1.dividedBy(dur2); + } + //----------------------------------------------------------------------- // negated() //-----------------------------------------------------------------------