
178
CHAPTER 7 
■  TRAITS AND TYPES AND GNARLY STUFF FOR ARCHITECTS
Next, we define a bunch of implicit methods that convert from Int or Long into a 
TimeSpanBuilder. This allows the methods such as minutes or days on TimeSpanBuilder 
to appear to be part of 
Int and Long.
4
  implicit def longToTimeSpanBuilder(in: Long): TimeSpanBuilder = 
                   TimeSpanBuilder(in)
  implicit def intToTimeSpanBuilder(in: Int): TimeSpanBuilder = TimeSpanBuilder(in)
And we define a helper method that gets the current time in milliseconds:
  def millis = System.currentTimeMillis
We define the TimeSpan class that represents a span of time. We can do math with other 
TimeSpans or convert this TimeSpan into a Date by calling the later or ago methods. TimeSpan 
extends the 
Ordered trait so that we can compare and sort TimeSpans.
  case class TimeSpan(millis: Long) extends Ordered[TimeSpan] {
    def later = new Date(millis + TimeHelpers.millis)
    def ago = new Date(TimeHelpers.millis - millis)
    def +(in: TimeSpan) = TimeSpan(this.millis + in.millis)
    def -(in: TimeSpan) = TimeSpan(this.millis - in.millis)
We compare this TimeSpan to another to satisfy the requirements of the Ordered trait:
    def compare(other: TimeSpan) = millis compare other.millis
  }
Next, we define a companion object that has an implicit method that will convert a 
TimeSpan into a Long. We’ll go into more depth about implicit scoping rules in the next 
subsection, but briefly, if there is an 
object with the same name as a class, that object 
is considered a companion 
object. If there are any implicit conversions defined in the 
companion 
object, they will be consulted if an instance of the class needs to be converted. 
We define an implicit conversion from 
TimeSpan to Long in the companion object. This will 
result in 
TimeSpan instances being automatically converted to Long if the TimeSpan is 
assigned to a 
Long variable or passed as a parameter that requires a Long.
  object TimeSpan {
    implicit def tsToMillis(in: TimeSpan): Long = in.millis
  }
4. We have to define separate implicit conversions for Int and Long because the Scala compiler will not 
automatically chain implicit conversions. To Scala, Int and Long are different types, but it will convert 
Int to Long because of the implicit conversion in Predef.
19897ch07.fm  Page 178  Monday, April 20, 2009  4:36 PM