Clojure: Writing JSON to a file - "Exception Don't know how to write JSON of class org.joda.time.DateTime"
As I mentioned in an earlier post I’ve been transforming Clojure hash’s into JSON strings using data.json but ran into trouble while trying to parse a hash which contained a Joda Time DateTime instance.
The date in question was constructed like this:
(ns json-date-example
(:require [clj-time.format :as f])
(:require [clojure.data.json :as json]))
(defn as-date [date-field]
(f/parse (f/formatter "dd MMM YYYY") date-field ))
(def my-date
(as-date "18 Mar 2012"))
And when I tried to convert a hash containing that object into a string I got the following exception:
> (json/write-str {:date my-date)})
java.lang.Exception: Don't know how to write JSON of class org.joda.time.DateTime
at clojure.data.json$write_generic.invoke (json.clj:367)
clojure.data.json$eval2818$fn__2819$G__2809__2826.invoke (json.clj:284)
clojure.data.json$write_object.invoke (json.clj:333)
clojure.data.json$eval2818$fn__2819$G__2809__2826.invoke (json.clj:284)
clojure.data.json$write.doInvoke (json.clj:450)
clojure.lang.RestFn.invoke (RestFn.java:425)
Luckily it’s quite easy to get around this by passing a function to write-str that converts the DateTime into a string representation before writing that part of the hash to a string.
The function looks like this:
(defn as-date-string [date]
(f/unparse (f/formatter "dd MMM YYYY") date))
(defn date-aware-value-writer [key value]
(if (= key :date) (as-date-string value) value))
And we make use of the writer like so:
> (json/write-str {:date my-date} :value-fn date-aware-value-writer)
"{\"date\":\"18 Mar 2012\"}"
If we want to read that string back again and reify our date we create a reader function which converts a string into a DateTime. The as-date function from the beginning of this post does exactly what we want so we’ll use that:
(defn date-aware-value-reader [key value]
(if (= key :date) (as-date value) value))
We can then pass the reader as an argument to read-str:
> (json/read-str "{\"date\":\"18 Mar 2012\"}" :value-fn date-aware-value-reader :key-fn keyword)
{:date #<DateTime 2012-03-18T00:00:00.000Z>}
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.