The Look
Ever since Martin Odersky gave us Generics in Java 5, we've become comfortable with reading parameterized types like Set<String> ("Set of String") for container classes. Unsurprisingly, with the move to Odersky's Scala has come further use of parameterization; for example Try[Double] and Future[User]. Essentially, I wanted a type that looked like this. Hence:val pierreTime: TimeInZone[Paris] val johnTime: TimeInZone[Melbourne] val canonicalTime: TimeInZone[UTC]
Behaviour
I want wrong code to look wrong but more than that, I want the compiler to consider it wrong too:
val pierreTime: TimeInZone[Paris]
def doSomethingInMelbourne(mTime: TimeInZone[Melbourne]) ...
// later...
doSomethingInMelbourne(pierreTime)
^
[error] type mismatch;
[error] found : TimeInZone[Paris]
[error] required: TimeInZone[Melbourne]
Functional Familiarity
I'm only a tiny way down the path to true functional-programming enlightenment. Hell, I've only just started looking at Scalaz, mainly thanks to eed3si9n's excellent tutorials.But the following patterns seem pretty sensible to me:
map from one timezone to another
The instant-in-time is unchanged, but the type changes, and the local time changes too:val pierreTime: TimeInZone[Paris] // Local: 2015-04-29T09:15:49.739+02:00 // Millis (UTC): 1430291749739 val johnTime: TimeInZone[Melbourne] = pierreTime.map[Melbourne] // Local: 2015-04-29T17:15:49.739+10:00 // Millis (UTC): 1430291749739
transform the time inside the container
I can make adjustments* to the DateTime contained within the TimeInZone[T] using any Joda-Time method that returns another DateTime:val pierreTime: TimeInZone[Paris] // Local: 2015-04-29T09:15:49.739+02:00 val pierreWakeUpTime: TimeInZone[Paris] = pierreTime.transform(_.withTime(7,0,0,0)) // Local: 2015-04-29T07:00:00.000+02:00 val pierreLunchTime: TimeInZone[Paris] = pierreTime.transform(_.plusHours(4)) // Local: 2015-04-29T13:15:49.739+02:00
(*) Everything is immutable (including within Joda-Time) so "adjustments" naturally result in a new object being returned. Do we have a word yet for "A modified copy of an immutable thing"?
Companion-object for construction
I should be able to get a TimeInZone[T] via its companion object for every conceivable scenario:
// "Now" in whatever TZ my JVM is running in:
val myLocalTime: TimeInZone[TimeZone] = TimeInZone.now
// -> TimeInZone[Melbourne] UTC: '2015-04-28T12:37:00.000Z'
// "Now" in the given TZ:
val myParisTime: TimeInZone[TimeZone] = TimeInZone.now("Europe/Paris")
// -> TimeInZone[Paris] UTC: '2015-04-28T12:37:23.000Z'
// "Now" in UTC:
val myUTCTime: TimeInZone[UTC] = TimeInZone.nowUTC
// -> TimeInZone[UTC] UTC: '2015-04-28T12:37:28.000Z'
// If I pass millis, UTC is implied:
val myUTCTime: TimeInZone[UTC] = TimeInZone.fromUTCMillis(1430703466430)
// -> TimeInZone[UTC] UTC: '2015-05-04T01:37:46.430Z
// Reflective methods where the desired [TimeZone] affects the result:
// Give me "now" on the West Coast:
val paloAlto = TimeInZone[PST]
// -> TimeInZone[PST] UTC: '2015-05-04T01:37:56.430Z
// Give me "then" on the West Coast:
val paloAltoLastWeek = TimeInZone[PST](new DateTime().minusDays(7))
// -> TimeInZone[PST] UTC: '2015-04-28T01:37:59.430Z
No comments:
Post a Comment
Comments welcome - spam is not. Spam will be detected, deleted and the source IP blocked.