Strongly Typed Time for Scala.
See
- http://blog.themillhousegroup.com/2015/04/strongly-typed-time-part-1-rationale.html
- http://blog.themillhousegroup.com/2015/05/strongly-typed-time-part-2-design.html
- http://blog.themillhousegroup.com/2015/07/strongly-typed-time-part-3-application.html
Bring in the library by adding the following to your build.sbt
.
- The release repository:
resolvers ++= Seq(
"Millhouse Bintray" at "http://dl.bintray.com/themillhousegroup/maven"
)
- The dependency itself (for Scala 2.11 and 2.12):
libraryDependencies ++= Seq(
"com.themillhousegroup" %% "arallon" % "0.1.49"
)
Once you have arallon added to your project, you can start using it like this:
import com.themillhousegroup.arallon._
import com.themillhousegroup.arallon.zones._
val nowInParis = TimeInZone[Paris]
// TimeInZone[Paris] UTC: '2015-05-10T03:04:15.876Z' Local: '2015-05-10T05:04:15.876+02:00'
val fromAJavaTimeZoneString:TimeInZone[TimeZone] = TimeInZone.now("Europe/Paris")
val now:TimeInZone[UTC] = TimeInZone.nowUTC
val fromMillis:TimeInZone[UTC] = TimeInZone.fromUTCMillis(123456789)
val fromMillisInTimeZone:TimeInZone[TimeZone] = TimeInZone.fromMillis(123456789, "Europe/Paris")
val fromADateTime:TimeInZone[Berlin] = TimeInZone.fromUTCTo[Berlin](aJodaDateTimeInUTC)
val fromADateTimeToUTC:TimeInZone[UTC] = TimeInZone.fromUTC(aJodaDateTimeInUTC)
val fromADateTime:TimeInZone[Berlin] = TimeInZone[Berlin](aBerlinJodaDateTime)
val inNamedZone:TimeInZone[TimeZone] = TimeInZone("America/New_York", aNewYorkJodaDateTime)
val threePMParisConferenceCall = nowInParis.transform(_.withTime(15,0,0,0))
// TimeInZone[Paris] UTC: '2015-05-10T13:00:00.000Z' Local: '2015-05-10T15:00:00.000+02:00
val wakeUpCall = threePMParisConferenceCall.map[Sydney]
// TimeInZone[Sydney] UTC: '2015-05-10T13:00:00.000Z' Local: '2015-05-10T23:00:00.000+10:00'
Notice how performing the map
to Sydney-time didn't change the instant being referred to - which is what you want if you're trying to join a conference call starting at that instant.
If you're looking for something client-side to generate a nice IANA string (like Europe/Paris
) take a look at
jstimezonedetect on GitHub - pass that to your Scala server-side and you can be strongly-typed
from then on.
import com.themillhousegroup.arallon.traits.TimeInZoneSerializing
val t = TimeInZone[Paris]
val s = t.serialize(t)
// Gives: "435363632Z:Europe/Paris"
val t2:TimeInZone[TimeZone] = TimeInZoneSerializing.deserialize(s)
- The fantastic Joda-Time does all the heavy lifting
The project is named after a fictional island in Episode 6 of the first season of HBO's Silicon Valley. The island was being built directly on the International Date Line - half in one timezone (and hence day), half in the other.
The name appealed for a couple of reasons - firstly, dealing with time on such an island would be hugely annoying and error-prone. Secondly, the construction of the island itself was fully automated using robotics and computers - no humans were involved.
The aim of this project is to approach that level of automation, where the compiler ensures that errors don't occur when working with timezones.