From e3d3e1665d150869be4be40b9ce42690e9e9d247 Mon Sep 17 00:00:00 2001 From: Yaroslav Klymko Date: Mon, 10 Jun 2013 17:57:47 +0300 Subject: Add Duration.toCoarsest method --- .../scala/concurrent/duration/Duration.scala | 36 ++++++++++++++++++++++ test/files/run/duration-coarsest.scala | 28 +++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 test/files/run/duration-coarsest.scala 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 + *

+ * 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 -- cgit v1.2.3