--- old/src/java.base/share/classes/java/time/Duration.java 2015-11-30 14:22:17.631101000 +0300 +++ new/src/java.base/share/classes/java/time/Duration.java 2015-11-30 14:22:17.451101000 +0300 @@ -61,6 +61,7 @@ */ package java.time; +import static java.time.LocalTime.MINUTES_PER_HOUR; import static java.time.LocalTime.NANOS_PER_SECOND; import static java.time.LocalTime.SECONDS_PER_DAY; import static java.time.LocalTime.SECONDS_PER_HOUR; @@ -973,7 +974,7 @@ if (multiplicand == 1) { return this; } - return create(toSeconds().multiply(BigDecimal.valueOf(multiplicand))); + return create(toBigDecimalSeconds().multiply(BigDecimal.valueOf(multiplicand))); } /** @@ -992,7 +993,7 @@ if (divisor == 1) { return this; } - return create(toSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN)); + return create(toBigDecimalSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN)); } /** @@ -1001,7 +1002,7 @@ * * @return the total length of the duration in seconds, with a scale of 9, not null */ - private BigDecimal toSeconds() { + private BigDecimal toBigDecimalSeconds() { return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9)); } @@ -1168,6 +1169,19 @@ } /** + * Gets the number of seconds in this duration. + *

+ * This returns the total number of seconds in the duration + *

+ * This instance is immutable and unaffected by this method call. + * + * @return the number of seconds in the duration, may be negative + */ + public long toSeconds() { + return seconds; + } + + /** * Converts this duration to the total length in milliseconds. *

* If this duration is too large to fit in a {@code long} milliseconds, then an @@ -1201,6 +1215,100 @@ return totalNanos; } + /** + * Extracts the number of days in the duration. + *

+ * This returns the total number of days in the duration by dividing the + * number of seconds by 86400. + * This is based on the standard definition of a day as 24 hours. + *

+ * This instance is immutable and unaffected by this method call. + * + * @return the number of days in the duration, may be negative + */ + public long toDaysPart(){ + return seconds / SECONDS_PER_DAY; + } + + /** + * Extracts the number of hours part in the duration. + *

+ * This returns the number of remaining hours when dividing {@link #toHours} + * by hours in a day. + * This is based on the standard definition of a day as 24 hours. + *

+ * This instance is immutable and unaffected by this method call. + * + * @return the number of hours part in the duration, may be negative + */ + public int toHoursPart(){ + return (int) (toHours() % 24); + } + + /** + * Extracts the number of minutes part in the duration. + *

+ * This returns the number of remaining minutes when dividing {@link #toMinutes} + * by minutes in an hour. + * This is based on the standard definition of an hour as 60 minutes. + *

+ * This instance is immutable and unaffected by this method call. + * + * @return the number of minutes parts in the duration, may be negative + * may be negative + */ + public int toMinutesPart(){ + return (int) (toMinutes() % MINUTES_PER_HOUR); + } + + /** + * Extracts the number of seconds part in the duration. + *

+ * This returns the remaining seconds when dividing {@link #toSeconds} + * by seconds in a minute. + * This is based on the standard definition of a minute as 60 seconds. + *

+ * This instance is immutable and unaffected by this method call. + * + * @return the number of seconds parts in the duration, may be negative + */ + public int toSecondsPart(){ + return (int) (seconds % SECONDS_PER_MINUTE); + } + + /** + * Extracts the number of milliseconds part of the duration. + *

+ * This returns the milliseconds part by dividing the number of nanoseconds by 1,000,000. + * The length of the duration is stored using two fields - seconds and nanoseconds. + * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to + * the length in seconds. + * The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}. + *

+ * This instance is immutable and unaffected by this method call. + * + * @return the number of milliseconds part of the duration. + */ + public int toMillisPart(){ + return nanos / 1000_000; + } + + /** + * Get the nanoseconds part within seconds of the duration. + *

+ * The length of the duration is stored using two fields - seconds and nanoseconds. + * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to + * the length in seconds. + * The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}. + *

+ * This instance is immutable and unaffected by this method call. + * + * @return the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999 + */ + public int toNanosPart(){ + return nanos; + } + //----------------------------------------------------------------------- /** * Compares this duration to the specified {@code Duration}. @@ -1208,7 +1316,7 @@ * The comparison is based on the total length of the durations. * It is "consistent with equals", as defined by {@link Comparable}. * - * @param otherDuration the other duration to compare to, not null + * @param otherDuration the other duration to compare to, not null * @return the comparator value, negative if less, positive if greater */ @Override @@ -1226,7 +1334,7 @@ *

* The comparison is based on the total length of the durations. * - * @param otherDuration the other duration, null returns false + * @param otherDuration the other duration, null returns false * @return true if the other duration is equal to this one */ @Override --- old/test/java/time/tck/java/time/TCKDuration.java 2015-11-30 14:22:18.195101000 +0300 +++ new/test/java/time/tck/java/time/TCKDuration.java 2015-11-30 14:22:18.008101000 +0300 @@ -2475,6 +2475,147 @@ } //----------------------------------------------------------------------- + // toSeconds() + //----------------------------------------------------------------------- + @DataProvider(name="toSeconds_provider") + Object[][] provider_toSeconds() { + return new Object[][] { + {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 31556926L}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -31556927L}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, 123_456_789), -31556926L}, + {Duration.ofSeconds(0), 0L}, + {Duration.ofSeconds(0, 123_456_789), 0L}, + {Duration.ofSeconds(0, -123_456_789), -1L}, + {Duration.ofSeconds(Long.MAX_VALUE), 9223372036854775807L}, + {Duration.ofSeconds(Long.MIN_VALUE), -9223372036854775808L}, + }; + } + + @Test(dataProvider="toSeconds_provider") + public void test_toSeconds(Duration dur, long seconds) { + assertEquals(dur.toSeconds(), seconds); + } + + //----------------------------------------------------------------------- + // toDaysPart() + //----------------------------------------------------------------------- + @DataProvider(name="toDaysPart_provider") + Object[][] provider_toDaysPart() { + return new Object[][] { + {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 365L}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -365L}, + {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 123_456_789), 0L}, + {Duration.ofDays(365), 365L}, + {Duration.ofHours(2), 0L}, + {Duration.ofHours(-2), 0L}, + }; + } + + @Test(dataProvider="toDaysPart_provider") + public void test_toDaysPart(Duration dur, long days) { + assertEquals(dur.toDaysPart(), days); + } + + //----------------------------------------------------------------------- + // toHoursPart() + //----------------------------------------------------------------------- + @DataProvider(name="toHoursPart_provider") + Object[][] provider_toHoursPart() { + return new Object[][] { + {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 5}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -5}, + {Duration.ofSeconds(48 * 60 + 46, 123_456_789), 0}, + {Duration.ofHours(2), 2}, + {Duration.ofHours(-2), -2}, + }; + } + + @Test(dataProvider="toHoursPart_provider") + public void test_toHoursPart(Duration dur, int hours) { + assertEquals(dur.toHoursPart(), hours); + } + + //----------------------------------------------------------------------- + // toMinutesPart() + //----------------------------------------------------------------------- + @DataProvider(name="toMinutesPart_provider") + Object[][] provider_toMinutesPart() { + return new Object[][] { + {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 48}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -48}, + {Duration.ofSeconds(46, 123_456_789),0}, + {Duration.ofMinutes(48), 48}, + {Duration.ofHours(2), 0}, + {Duration.ofHours(-2),0}, + }; + } + + @Test(dataProvider="toMinutesPart_provider") + public void test_toMinutesPart(Duration dur, int minutes) { + assertEquals(dur.toMinutesPart(), minutes); + } + + //----------------------------------------------------------------------- + // toSecondsPart() + //----------------------------------------------------------------------- + @DataProvider(name="toSecondsPart_provider") + Object[][] provider_toSecondsPart() { + return new Object[][] { + {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 46}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -47}, + {Duration.ofSeconds(0, 123_456_789), 0}, + {Duration.ofSeconds(46), 46}, + {Duration.ofHours(2), 0}, + {Duration.ofHours(-2), 0}, + }; + } + + @Test(dataProvider="toSecondsPart_provider") + public void test_toSecondsPart(Duration dur, int seconds) { + assertEquals(dur.toSecondsPart(), seconds); + } + + //----------------------------------------------------------------------- + // toMillisPart() + //----------------------------------------------------------------------- + @DataProvider(name="toMillisPart_provider") + Object[][] provider_toMillisPart() { + return new Object[][] { + {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 123}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), 876}, + {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 0), 0}, + {Duration.ofMillis(123), 123}, + {Duration.ofHours(2), 0}, + {Duration.ofHours(-2), 0}, + }; + } + + @Test(dataProvider="toMillisPart_provider") + public void test_toMillisPart(Duration dur, int millis) { + assertEquals(dur.toMillisPart(), millis); + } + + //----------------------------------------------------------------------- + // toNanosPart() + //----------------------------------------------------------------------- + @DataProvider(name="toNanosPart_provider") + Object[][] provider_toNanosPart() { + return new Object[][] { + {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 123_456_789}, + {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), 876_543_211}, + {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 0), 0}, + {Duration.ofNanos(123_456_789), 123_456_789}, + {Duration.ofHours(2), 0}, + {Duration.ofHours(-2), 0}, + }; + } + + @Test(dataProvider="toNanosPart_provider") + public void test_toNanosPart(Duration dur, int nanos) { + assertEquals(dur.toNanosPart(), nanos); + } + + //----------------------------------------------------------------------- // compareTo() //----------------------------------------------------------------------- @Test