08 Feb 2014

In Clojure, the reader-literal #inst reads & writes java.util.Dates. For instance:

(type #inst "2014-02-06T00:00:00Z") ;=> java.util.Date

(pr-str (java.util.Date.)) ;=> #inst "2014-02-08T15:54:49.949-00:00"

But it’s possible to replace that behaviour to read and write Joda time instances. Here’s how:

DISCLAIMER This may be a terrible idea. In fact it probably is. Go away, unless you enjoy standing in the middle of a thunderstorm cackling, “It’s Alive! It’s Alive!”

Still with me? That’s the spirit!

First you’ll need clj-time. Add this to your project.clj’s :dependencies:

[clj-time "0.6.0"]

Second To get Clojure to read #insts as org.joda.time.DateTime classes, add this to src/data_readers.clj:

{inst clj-time.format/parse}

That just switches out the function that turns strings into date objects. Restart your REPL session to pick that up.

Third You’ll need to implement a printing method, so that the classes are written as #inst-tagged strings:

  (defmethod print-dup org.joda.time.DateTime
    [o writer]
    (.write writer (format "#inst \"%s\"" o)))

Make sure that code’s been imported into any namespace where you want this to work. Now you can say:

  {:start #inst "2014-02-06T00:00:00.000-00:00"
   :end #inst "2014-02-06T02:00:00.000-00:00"}

And get a map whose values are Joda DateTime objects.

As I say, this is probably a bad idea. It’ll unexpectedly break things for people. But it’s a fun hack anyway, so I thought I’d record it.

comments powered by Disqus