--- old/src/java.base/share/classes/java/time/Duration.java 2016-03-25 15:38:19.846426060 +0300 +++ new/src/java.base/share/classes/java/time/Duration.java 2016-03-25 15:38:19.570426060 +0300 @@ -1350,6 +1350,48 @@ return nanos; } + + //----------------------------------------------------------------------- + /** + * Returns a copy of this {@code Duration} truncated to the specified unit. + *
+ * Truncating the duration returns a copy of the original with fields + * smaller than the specified unit set to zero. + * For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will + * round down to the nearest minute, setting the seconds and nanoseconds to zero. + *
+ * The unit must have a {@linkplain TemporalUnit#getDuration() duration} + * that divides into the length of a standard day without remainder. + * This includes all supplied time units on {@link ChronoUnit} and + * {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception. + *
+ * This instance is immutable and unaffected by this method call.
+ *
+ * @param unit the unit to truncate to, not null
+ * @return a {@code Duration} based on this duration with the time truncated, not null
+ * @throws DateTimeException if the unit is invalid for truncation
+ * @throws UnsupportedTemporalTypeException if the unit is not supported
+ */
+ public Duration truncatedTo(TemporalUnit unit) {
+ Objects.requireNonNull(unit, "unit");
+ if (unit == ChronoUnit.SECONDS) {
+ return new Duration(seconds, 0);
+ } else if (unit == ChronoUnit.NANOS) {
+ return this;
+ }
+ Duration unitDur = unit.getDuration();
+ if (unitDur.getSeconds() > LocalTime.SECONDS_PER_DAY) {
+ throw new UnsupportedTemporalTypeException("Unit is too large to be used for truncation");
+ }
+ long dur = unitDur.toNanos();
+ if ((LocalTime.NANOS_PER_DAY % dur) != 0) {
+ throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
+ }
+ long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
+ long result = Math.floorDiv(nod, dur) * dur ;
+ return plusNanos(result - nod);
+ }
+
//-----------------------------------------------------------------------
/**
* Compares this duration to the specified {@code Duration}.
--- old/test/java/time/tck/java/time/TCKDuration.java 2016-03-25 15:38:20.603426060 +0300
+++ new/test/java/time/tck/java/time/TCKDuration.java 2016-03-25 15:38:20.310426060 +0300
@@ -65,9 +65,11 @@
import static java.time.temporal.ChronoUnit.MICROS;
import static java.time.temporal.ChronoUnit.MILLIS;
import static java.time.temporal.ChronoUnit.MINUTES;
+import static java.time.temporal.ChronoUnit.MONTHS;
import static java.time.temporal.ChronoUnit.NANOS;
import static java.time.temporal.ChronoUnit.SECONDS;
import static java.time.temporal.ChronoUnit.WEEKS;
+import static java.time.temporal.ChronoUnit.YEARS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@@ -2287,6 +2289,131 @@
}
//-----------------------------------------------------------------------
+ // truncated(TemporalUnit)
+ //-----------------------------------------------------------------------
+ TemporalUnit NINETY_MINS = new TemporalUnit() {
+ @Override
+ public Duration getDuration() {
+ return Duration.ofMinutes(90);
+ }
+ @Override
+ public boolean isDurationEstimated() {
+ return false;
+ }
+ @Override
+ public boolean isDateBased() {
+ return false;
+ }
+ @Override
+ public boolean isTimeBased() {
+ return true;
+ }
+ @Override
+ public boolean isSupportedBy(Temporal temporal) {
+ return false;
+ }
+ @Override
+ public