In Clojure, I frequently use org.joda.time
via
clj-time as a much nicer
alternative to the java.util.*
classes. But since
transit doesn’t have a
built-in encoder to write JodaTime types as dates, I had to write my
own. It took a bit of digging through
transit-clj to figure out
how, but it’s pretty simple.
When you write to transit in Clojure, you provide a writer via the
transit/writer
function; this function takes a map of options
including handlers for non-default types:
(transit/writer out :json {:handlers {org.joda.time.DateTime joda-time-writer}})
So all we need now is to actually define that joda-time-writer
. The
manual way is to reify
a com.cognitect.transit.WriteHandler
, but
transit-clj provides an easy helper function that just takes the
functions for providing the tag, representation, and string
representation. In this case, I just yanked what Transit does to
java.util.Time
s, coerced the Joda types to those first, and carried
on. Here’s the code:
(def joda-time-writer
(transit/write-handler
(constantly "m")
(fn [v] (-> v coerce/to-date .getTime))
(fn [v] (-> v coerce/to-date .getTime .toString))))
Update 3 Sep 2015
Daniel Compton sends along an improvement to this snippet that doesn’t require the Java Date conversion:
(def joda-time-writer
(transit/write-handler
(constantly "m")
(fn [v] (-> ^ReadableInstant v .getMillis))
(fn [v] (-> ^ReadableInstant v .getMillis .toString))))
See more on Github.