I was reading the scala doc for the scala.concurrent.duration.Duration
class, and I just discovered that it starts with:
This class is not meant as a general purpose representation of time, it is optimized for the needs of scala.concurrent.
Why are the implications of this statement? What's a better alternative?
I guess I'm partially responsible for this.
The general issue here is that time system are hard. Really, really, really hard.
The Akka developers who worked on standardizing Futures needed a construct to describe the length between two “anonymous” points in time to implement their functionality. Duration
was built to solve this specific requirement.
My concern was that people might start using this time-related class for things it wasn't designed for bringing us into a troublesome situation comparable to java.util.Date
/java.util.Calendar
(not quite because Duration
actually works for its use-case) where tons of people would misuse it as some kind of scala.time
which it was never intended to be.
That's why it has this note and is packaged into scala.concurrent.duration
instead of e. g. scala.time
.
I look forward to the java.time
package shipping with Java 8. It might be possible to standardize on that in the future which would improve interoperability a bit and would have the additional benefit of being designed for a much broader use-case. (It will probably take a long time until Scala uses Java 8 as a baseline, though...)
Time can be represented in various ways depending on your needs. I personally have used:
Long
— a lot of tools take it directlyUpdated: java.time.*
thanks to @Vladimir Matveev
The package is designed by the author of Joda Time (Stephen Colebourne). He says it is designed better.
Joda Time
java.util.Date
Separate hierarchy of classes:
trait Time
case class ExactTime(timeMs:Long) extends Time
case object Now extends Time
case object ASAP extends Time
case class RelativeTime(origin:Time, deltaMs:Long) extends Time
Ordered time representation:
case class History[T](events:List[T])
Model time. Once I had a global object Timer
with var currentTime:Long
:
object Timer {
private var currentTimeValue:Long
def currentTimeMs = currentTimeValue
def currentTimeMs_=(newTime:Long) { ... some checks and notifications}
def pseudoRandom:Double = ...
}
And everywhere in the program I called Timer.currentTimeMs
to get the time. It allows to write deterministic tests with controlled time shift. (Beware of global variable! Now I prefer to use separate instances of Timer
to avoid concurrency issues.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With