scala.concurrent.duration

package duration

Type Members

case class Deadline extends Ordered[Deadline] with Product with Serializable

This class stores a deadline, as obtained via Deadline.now or the duration DSL:

import scala.concurrent.duration._
3.seconds.fromNow

Its main purpose is to manage repeated attempts to achieve something (like awaiting a condition) by offering the methods hasTimeLeft and timeLeft . All durations are measured according to System.nanoTime aka wall-time; this does not take into account changes to the system clock (such as leap seconds).

implicit final class DoubleMult extends AnyVal

sealed abstract class Duration extends Serializable with Ordered[Duration]

Utility for working with java.util.concurrent.TimeUnit durations.

  • This class is not meant as a general purpose representation of time, it is optimized for the needs of scala.concurrent .*

Basic Usage

Examples:

import scala.concurrent.duration._

val duration = Duration(100, MILLISECONDS)
val duration = Duration(100, "millis")

duration.toNanos
duration < 1.second
duration <= Duration.Inf
  • Invoking inexpressible conversions (like calling toSeconds on an infinite duration) will throw an IllegalArgumentException.*

Implicits are also provided for Int, Long and Double. Example usage:

import scala.concurrent.duration._

val duration = 100 millis
  • The DSL provided by the implicit conversions always allows construction of finite durations, even for infinite Double inputs; use Duration.Inf instead.*

Extractors, parsing and arithmetic are also included:

val d = Duration("1.2 µs")
val Duration(length, unit) = 5 millis
val d2 = d * 2.5
val d3 = d2 + 1.millisecond

Handling of Time Units

Calculations performed on finite durations always retain the more precise unit of either operand, no matter whether a coarser unit would be able to exactly express the same duration. This means that Duration can be used as a lossless container for a (length, unit) pair if it is constructed using the corresponding methods and no arithmetic is performed on it; adding/subtracting durations should in that case be done with care.

Correspondence to Double Semantics

The semantics of arithmetic operations on Duration are two-fold:

  • exact addition/subtraction with nanosecond resolution for finite durations, independent of the summands’ magnitude
  • isomorphic to java.lang.Double when it comes to infinite or undefined values

The conversion between Duration and Double is done using Duration.toUnit (with unit NANOSECONDS) and Duration.fromNanos(Double)

Ordering

The default ordering is consistent with the ordering of Double numbers, which means that Undefined is considered greater than all other durations, including Duration.Inf.

trait DurationConversions extends Any

implicit final class DurationDouble extends AnyVal with DurationConversions

implicit final class DurationInt extends AnyVal with DurationConversions

implicit final class DurationLong extends AnyVal with DurationConversions

final class FiniteDuration extends Duration

This class represents a finite duration. Its addition and subtraction operators are overloaded to retain this guarantee statically. The range of this class is limited to +-(2^63-1)ns, which is roughly 292 years.

implicit final class IntMult extends AnyVal

implicit final class LongMult extends AnyVal

type TimeUnit = java.util.concurrent.TimeUnit

Value Members

object Deadline extends Serializable

object Duration extends Serializable

object DurationConversions

This object just holds some cogs which make the DSL machine work, not for direct consumption.

object FiniteDuration extends Serializable

object fromNow

This object can be used as closing token for declaring a deadline at some future point in time:

import scala.concurrent.duration._

val deadline = 3 seconds fromNow

object span

This object can be used as closing token if you prefer dot-less style but do not want to enable language.postfixOps:

import scala.concurrent.duration._

val duration = 2 seconds span

Value Members From scala.concurrent.duration

final val DAYS: java.util.concurrent.TimeUnit(DAYS)

(defined at scala.concurrent.duration)

implicit def durationToPair(d: Duration): (Long, TimeUnit)

(defined at scala.concurrent.duration)

implicit def pairIntToDuration(p: (Int, TimeUnit)): Duration

(defined at scala.concurrent.duration)

implicit def pairLongToDuration(p: (Long, TimeUnit)): FiniteDuration

(defined at scala.concurrent.duration)

Full Source:

package scala.concurrent

import scala.language.implicitConversions

package object duration {
  /**
   * This object can be used as closing token if you prefer dot-less style but do not want
   * to enable language.postfixOps:
   *
   * {{{
   * import scala.concurrent.duration._
   *
   * val duration = 2 seconds span
   * }}}
   */
  object span

  /**
   * This object can be used as closing token for declaring a deadline at some future point
   * in time:
   *
   * {{{
   * import scala.concurrent.duration._
   *
   * val deadline = 3 seconds fromNow
   * }}}
   */
  object fromNow

  type TimeUnit          = java.util.concurrent.TimeUnit
  final val DAYS         = java.util.concurrent.TimeUnit.DAYS
  final val HOURS        = java.util.concurrent.TimeUnit.HOURS
  final val MICROSECONDS = java.util.concurrent.TimeUnit.MICROSECONDS
  final val MILLISECONDS = java.util.concurrent.TimeUnit.MILLISECONDS
  final val MINUTES      = java.util.concurrent.TimeUnit.MINUTES
  final val NANOSECONDS  = java.util.concurrent.TimeUnit.NANOSECONDS
  final val SECONDS      = java.util.concurrent.TimeUnit.SECONDS

  implicit def pairIntToDuration(p: (Int, TimeUnit)): Duration         = Duration(p._1.toLong, p._2)
  implicit def pairLongToDuration(p: (Long, TimeUnit)): FiniteDuration = Duration(p._1, p._2)
  implicit def durationToPair(d: Duration): (Long, TimeUnit)           = (d.length, d.unit)

  implicit final class DurationInt(private val n: Int) extends AnyVal with DurationConversions {
    override protected def durationIn(unit: TimeUnit): FiniteDuration = Duration(n.toLong, unit)
  }

  implicit final class DurationLong(private val n: Long) extends AnyVal with DurationConversions {
    override protected def durationIn(unit: TimeUnit): FiniteDuration = Duration(n, unit)
  }

  implicit final class DurationDouble(private val d: Double) extends AnyVal with DurationConversions {
    override protected def durationIn(unit: TimeUnit): FiniteDuration =
      Duration(d, unit) match {
        case f: FiniteDuration => f
        case _ => throw new IllegalArgumentException("Duration DSL not applicable to " + d)
      }
  }

  /*
   * Avoid reflection based invocation by using non-duck type
   */
  implicit final class IntMult(private val i: Int) extends AnyVal {
    def *(d: Duration) = d * i.toDouble
    def *(d: FiniteDuration) = d * i.toLong
  }

  implicit final class LongMult(private val i: Long) extends AnyVal {
    def *(d: Duration) = d * i.toDouble
    def *(d: FiniteDuration) = d * i.toLong
  }

  implicit final class DoubleMult(private val f: Double) extends AnyVal {
    def *(d: Duration) = d * f.toDouble
  }
}