Clojure: serializing and parsing date/time to/from file?

1.2k Views Asked by At

I'd like to store some test data to a file and read it out again in my tests. The data is a sequence of Clojure maps, one property of which is a clj-time (org.joda.time.DateTime) date/time. When I write the value to the file (with spit), it serializes as #<DateTime 2014-10-03T12:57:15.000Z>. When I try to read it back (with slurp), I get:

RuntimeException Unreadable form  clojure.lang.Util.runtimeException (Util.java:221)

I guess that isn't surprising since without more information I don't see how it would know how to parse a DateTime. Is there some way to read these values and have them parsed properly or so I have to serialize them as strings and parse them manually when I read them back out?

2

There are 2 best solutions below

1
noisesmith On

Clojure comes with a tagged reader for java.util.Date

user> (java.util.Date.)
#inst "2014-10-28T19:46:50.183-00:00"
user> (pr-str (java.util.Date.))
"#inst \"2014-10-28T19:47:00.503-00:00\""
user> (read-string (pr-str (java.util.Date.)))
#inst "2014-10-28T19:47:11.626-00:00"

one option would be to convert from org.joda.time.DateTime to java.util.Date before writing to file, and convert back again after reading.

user> (.toDate (org.joda.time.DateTime.))
#inst "2014-10-28T19:50:34.859-00:00"
user> (org.joda.time.DateTime. (.toDate (org.joda.time.DateTime.)))
#<DateTime 2014-10-28T12:51:09.231-07:00>
0
Matthew Gertner On

@noisesmith's answer spurred me to research tagged readers in more detail (thanks @noisesmith!). It looks like https://gist.github.com/ragnard/4738185 will let me do what I want. Specifically, you can bind a new value to *data-readers* and tell the reader to parse the value any way you want.

In this case, I just want to read out my test data so I don't even need to modify the print-method and print-dup protocols. I just store the data as normal dates (#inst "...") and the use the with-joda-time-reader macro to read them out.