Increasingly Functional.
by Joshua Miller | on Twitter | on the web | on github

Custom Transit Writers In Clojure For JodaTime

September 2nd 2014

Tagged: clojure

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.Times, 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.