Question

I have a UUID and java util date which get literals as #uuid and #inst, how do I specify the uuid or date without referencing the literals themselves? clj-json does not like dealing with them and ends up throwing an error when I try generate-string

{:timestamp (java.util.Date.)}
;{:timestamp #inst "2013-05-17T13:45:24.095-00:00"}

;but as a string the date changes format
{:timestamp (str (java.util.Date.))}
{:timestamp "Fri May 17 09:45:44 EDT 2013"}

(json/generate-string {:uuid (java.util.UUID/randomUUID)}) 
;#uuid "d66cf77f-13b6-4291-95cd-c2bb40aa36b3"

java.lang.Exception: Cannot generate d66cf77f-13b6-4291-95cd-c2bb40aa36b3
JsonExt.java:96 clj_json.JsonExt$Generator.generate
JsonExt.java:83 clj_json.JsonExt$Generator.generate
JsonExt.java:103 clj_json.JsonExt.generate
core.clj:18 clj-json.core/generate-to-writer
core.clj:26 clj-json.core/generate-string
NO_SOURCE_FILE:32 myapp.handler/eval8390
Était-ce utile?

La solution

Not sure, but it looks like what you need:

user=> (str (java.util.UUID/randomUUID))
"91d7fcc5-d24d-4e33-a111-6ba69d14eb6a"

For date you need to choose right format. I.e.:

user=> (import java.text.SimpleDateFormat)
java.text.SimpleDateFormat
user=> (.format (SimpleDateFormat. "yyyy/MM/dd HH:mm:ss") (java.util.Date.))
"2013/05/17 16:49:58"

Autres conseils

You can use this library, which supports UUID and Dates https://github.com/dakrone/cheshire

According to the project page "Cheshire is fast JSON encoding, based off of clj-json and clojure-json, with additional features like Date/UUID/Set/Symbol encoding and SMILE support."

The timestamp is an object that has no "format". You can choose to format is as text yourself or use e.g. cheshire to generate JSON. Cheshire knows what kind of date format goes well with JSON and can do the conversion.

user> (def x (java.util.Date.))      
#'user/x                   ; x points to a Date object (not text)

Clojure printer knows how to represent binary objects to humans:

user> x
#inst "2015-02-13T06:24:09.629-00:00"
user> (pr-str x)
"#inst \"2015-02-13T06:24:09.629-00:00\""

You can choose a text representation yourself:

user> (str x)
"Fri Feb 13 08:24:09 EET 2015"       ; default format of java.util.Date
user> (.format (java.text.SimpleDateFormat. "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") x)
"2015-02-13T08:24:09.629+02:00"

Just to make the distinction clear, the object can also be presented as byte values, which is lossless:

user> (def outs (java.io.ByteArrayOutputStream.))
#'user/outs
user> (doto (java.io.ObjectOutputStream. outs) (.writeObject x) (.close))
#<ObjectOutputStream java.io.ObjectOutputStream@2bd682ed>
user> (seq (.toByteArray outs))
(-84 -19 0 5 115 114 0 14 106 97 118 97 46 117 116 105 108 46 68 97 116 101 104 106 -127 1 75 89 116 25 3 0 0 120 112 119 8 0 0 1 75 -127 -101 -39 -99 120)

For date and time stuff, you are better off just using clj-time, which is a wrapper around the joda time libraries. This avoids having to deal with the icky java date, time calendar, format stuff.

I also recently saw a clj-uuid library on github, which might make working with uuids a bit more clojurish

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top