1

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?

Matthew Gertner
  • 4,487
  • 2
  • 32
  • 54
  • Do you need to preserve the chronology field from `DateTime`? That will make your task much harder if you do. – Alex Oct 28 '14 at 21:11
  • Luckily we don't need this. It's just a testing fixture anyway so we can be quite specific about what we do and don't support. – Matthew Gertner Oct 29 '14 at 09:47

2 Answers2

1

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>
noisesmith
  • 20,076
  • 2
  • 41
  • 49
  • Is this better somehow than just storing them as strings? Ideally I'd like to find a solution that doesn't require pre/post-processing (see my answer). – Matthew Gertner Oct 29 '14 at 09:47
0

@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.

Matthew Gertner
  • 4,487
  • 2
  • 32
  • 54