I tried to follow the documentation for clojure.instant/read-instant-timestamp
, which reads:
clojure.instant/read-instant-timestamp To read an instant as a java.sql.Timestamp, bind *data-readers* to a map with this var as the value for the 'inst key. Timestamp preserves fractional seconds with nanosecond precision. The timezone offset will be used to convert into UTC.`
The following result was unexpected:
(do
(require '[clojure.edn :as edn])
(require '[clojure.instant :refer [read-instant-timestamp]])
(let [instant "#inst \"1970-01-01T00:00:09.999-00:00\""
reader-map {'inst #'read-instant-timestamp}]
;; This binding is not appearing to do anything.
(binding [*data-readers* reader-map]
;; prints java.util.Date -- unexpected
(->> instant edn/read-string class println)
;; prints java.sql.Timestamp -- as desired
(->> instant (edn/read-string {:readers reader-map}) class println))))
How can I use the *data-readers*
binding? Clojure version 1.5.1.
The *data-readers*
dynamic var seems to apply to the read-string
and read
functions from clojure.core
only.
(require '[clojure.instant :refer [read-instant-timestamp]])
(let [instant "#inst \"1970-01-01T00:00:09.999-00:00\""
reader-map {'inst #'read-instant-timestamp}]
;; This will read a java.util.Date
(->> instant read-string class println)
;; This will read a java.sql.Timestamp
(binding [*data-readers* reader-map]
(->> instant read-string class println)))
Browsing through the source code for clojure.edn
reader here, I couldn't find anything that would indicate that the same *data-readers*
var is used at all there.
clojure.core
's functions read
and read-string
use LispReader
(which uses the value from *data-readers*
), while the functions from clojure.edn
use the EdnReader
.
This edn
library is relatively new in Clojure so that might be the reason why the documentation string is not specific enough regarding edn
vs. core
reader, which can cause this kind of confusion.
Hope it helps.