Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove #inst and #uuid literals in clojure

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
like image 361
scape Avatar asked May 17 '13 13:05

scape


4 Answers

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"
like image 104
Alexey Kachayev Avatar answered Sep 28 '22 04:09

Alexey Kachayev


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

like image 33
kisai Avatar answered Sep 28 '22 03:09

kisai


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)
like image 25
jkj Avatar answered Sep 28 '22 04:09

jkj


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

like image 23
Tim X Avatar answered Sep 28 '22 04:09

Tim X