summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/concurrent/duration/Duration.scala36
-rw-r--r--test/files/run/duration-coarsest.scala28
2 files changed, 64 insertions, 0 deletions
diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala
index a24266bf19..9a8844b489 100644
--- a/src/library/scala/concurrent/duration/Duration.scala
+++ b/src/library/scala/concurrent/duration/Duration.scala
@@ -221,6 +221,8 @@ object Duration {
final def toMinutes: Long = fail("toMinutes")
final def toHours: Long = fail("toHours")
final def toDays: Long = fail("toDays")
+
+ final def toCoarsest: Duration = this
}
/**
@@ -520,6 +522,18 @@ sealed abstract class Duration extends Serializable with Ordered[Duration] {
* $ovf
*/
def plus(other: Duration) = this + other
+ /**
+ * Return duration which is equal to this duration but with a coarsest Unit, or self in case it is already the coarsest Unit
+ * <p/>
+ * Examples:
+ * {{{
+ * Duration(60, MINUTES).toCoarsest // Duration(1, HOURS)
+ * Duration(1000, MILLISECONDS).toCoarsest // Duration(1, SECONDS)
+ * Duration(48, HOURS).toCoarsest // Duration(2, DAYS)
+ * Duration(5, SECONDS).toCoarsest // Duration(5, SECONDS)
+ * }}}
+ */
+ def toCoarsest: Duration
}
object FiniteDuration {
@@ -691,6 +705,28 @@ final class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duratio
final def isFinite() = true
+ final def toCoarsest: Duration = {
+ def loop(length: Long, unit: TimeUnit): FiniteDuration = {
+ def coarserOrThis(coarser: TimeUnit, divider: Int) =
+ if (length % divider == 0) loop(length / divider, coarser)
+ else if (unit == this.unit) this
+ else FiniteDuration(length, unit)
+
+ unit match {
+ case DAYS => FiniteDuration(length, unit)
+ case HOURS => coarserOrThis(DAYS, 24)
+ case MINUTES => coarserOrThis(HOURS, 60)
+ case SECONDS => coarserOrThis(MINUTES, 60)
+ case MILLISECONDS => coarserOrThis(SECONDS, 1000)
+ case MICROSECONDS => coarserOrThis(MILLISECONDS, 1000)
+ case NANOSECONDS => coarserOrThis(MICROSECONDS, 1000)
+ }
+ }
+
+ if (unit == DAYS || length == 0) this
+ else loop(length, unit)
+ }
+
override def equals(other: Any) = other match {
case x: FiniteDuration => toNanos == x.toNanos
case _ => super.equals(other)
diff --git a/test/files/run/duration-coarsest.scala b/test/files/run/duration-coarsest.scala
new file mode 100644
index 0000000000..51cb79287a
--- /dev/null
+++ b/test/files/run/duration-coarsest.scala
@@ -0,0 +1,28 @@
+import scala.concurrent.duration._
+import scala.language.postfixOps
+
+object Test extends App {
+ List(
+ (60 minutes, 1 hour),
+ (2000 millis, 2 seconds),
+ (2000 micros, 2 millis),
+ (2000 nanos, 2 micros),
+ (2000000 nanos, 2 millis),
+ (48 hours, 2 days),
+ (5 seconds, 5 seconds),
+ (1 second, 1 second)
+ ) foreach {
+ case (x, expected) =>
+ val actual = x.toCoarsest
+ assert(actual.unit == expected.unit, s"$actual, $expected")
+ assert(actual.length == expected.length, s"$actual, $expected")
+ }
+
+ List(
+ 45 minutes,
+ 500 millis,
+ 1500 millis,
+ 23 hours,
+ 40 days
+ ) foreach (x => assert(x == x.toCoarsest, x))
+} \ No newline at end of file