in util-core/src/main/scala/com/twitter/util/Time.scala [99:193]
def unapply(x: This): Option[This] =
if (x.isFinite) Some(x) else None
}
/** Make a new `This` from the given number of nanoseconds */
def fromNanoseconds(nanoseconds: Long): This
def fromSeconds(seconds: Int): This = fromMilliseconds(1000L * seconds)
def fromMinutes(minutes: Int): This = fromMilliseconds(60L * 1000L * minutes)
def fromHours(hours: Int): This = fromMilliseconds(60L * 60L * 1000L * hours)
def fromDays(days: Int): This = fromMilliseconds(24L * 3600L * 1000L * days)
/**
* Make a new `This` from the given number of seconds.
* Because this method takes a Double, it can represent values less than a second.
* Note however that there is some slop in floating-point conversion that
* limits precision. Currently we can assume at least microsecond precision.
*/
def fromFractionalSeconds(seconds: Double): This =
fromNanoseconds((1000L * 1000L * 1000L * seconds).toLong)
def fromMilliseconds(millis: Long): This =
if (millis > 9223372036854L) Top
else if (millis < -9223372036854L) Bottom
else fromNanoseconds(TimeUnit.MILLISECONDS.toNanos(millis))
def fromMicroseconds(micros: Long): This =
if (micros > 9223372036854775L) Top
else if (micros < -9223372036854775L) Bottom
else fromNanoseconds(TimeUnit.MICROSECONDS.toNanos(micros))
}
/**
* A common trait for time-like values. It requires a companion
* `TimeLikeOps` module. `TimeLike`s are finite, but they must always
* have two sentinels: `Top` and `Bottom`. These act like positive
* and negative infinities: Arithmetic involving them preserves their
* values, and so on.
*
* `TimeLike`s are `Long`-valued nanoseconds, but have different
* interpretations: `Duration`s measure the number of nanoseconds
* between two points in time, while `Time` measure the number of
* nanoseconds since the Unix epoch (1 January 1970 00:00:00 UTC).
*
* TimeLike behave like '''boxed''' java Double values with respect
* to infinity and undefined values. In particular, this means that a
* `TimeLike`'s `Undefined` value is comparable to other values. In
* turn this means it can be used as keys in maps, etc.
*
* Overflows are also handled like doubles.
*/
trait TimeLike[This <: TimeLike[This]] extends Ordered[This] { self: This =>
protected def ops: TimeLikeOps[This]
/** The `TimeLike`'s value in nanoseconds. */
def inNanoseconds: Long
def inMicroseconds: Long = inNanoseconds / Duration.NanosPerMicrosecond
def inMilliseconds: Long = inNanoseconds / Duration.NanosPerMillisecond
def inLongSeconds: Long = inNanoseconds / Duration.NanosPerSecond
def inSeconds: Int =
if (inLongSeconds > Int.MaxValue) Int.MaxValue
else if (inLongSeconds < Int.MinValue) Int.MinValue
else inLongSeconds.toInt
// Units larger than seconds safely fit into 32-bits when converting from a 64-bit nanosecond basis
def inMinutes: Int = (inNanoseconds / Duration.NanosPerMinute).toInt
def inHours: Int = (inNanoseconds / Duration.NanosPerHour).toInt
def inDays: Int = (inNanoseconds / Duration.NanosPerDay).toInt
def inMillis: Long = inMilliseconds // (Backwards compatibility)
/**
* Returns a value/`TimeUnit` pair; attempting to return coarser grained
* values if possible (specifically: `TimeUnit.MINUTES`, `TimeUnit.SECONDS`
* or `TimeUnit.MILLISECONDS`) before resorting to the default
* `TimeUnit.NANOSECONDS`.
*/
def inTimeUnit: (Long, TimeUnit) = inNanoseconds match {
// allow for APIs that may treat TimeUnit differently if measured in very tiny units.
case ns if ns % Duration.NanosPerMinute == 0 => (inMinutes, TimeUnit.MINUTES)
case ns if ns % Duration.NanosPerSecond == 0 => (inSeconds, TimeUnit.SECONDS)
case ns if ns % Duration.NanosPerMillisecond == 0 => (inMilliseconds, TimeUnit.MILLISECONDS)
case ns => (ns, TimeUnit.NANOSECONDS)
}
/**
* Adds `delta` to this `TimeLike`. Adding `Duration.Top` results
* in the `TimeLike`'s `Top`, adding `Duration.Bottom` results in
* the `TimeLike`'s `Bottom`.
*/
def +(delta: Duration): This = {
// adds a to b while taking care of long overflow
def addNanos(a: Long, b: Long): This = {