【问题标题】:Remove #inst and #uuid literals in clojure删除 clojure 中的 #inst 和 #uuid 文字
【发布时间】:2013-05-17 13:31:36
【问题描述】:

我有一个 UUID 和 java util 日期,它们的文字为 #uuid 和 #inst,我如何在不引用文字本身的情况下指定 uuid 或日期? clj-json 不喜欢处理它们,当我尝试 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

【问题讨论】:

    标签: json clojure literals


    【解决方案1】:

    不确定,但看起来像你需要的:

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

    对于日期,您需要选择正确的格式。即:

    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"
    

    【讨论】:

    • 适用于 uuid 但对于 Date 它实际上改变了日期格式!我会更新问题,谢谢
    • 谢谢,我希望保留格式,以防我想使用它在 clojure 中轻松比较。我很好奇为什么它在转换为字符串时会改变格式
    • 看起来我可以很容易地比较它:(let [_ (str (java.util.Date.))] (java.util.Date._)) ;#inst "2013-05 -17T13:55:47.000-00:00"
    • @scape:#inst 引用的对象不是文本,也没有格式。您可以自己将其格式化为文本,或者如果您在 REPL 中将其打印出来,它会被表示为 ISO8601 时间戳。只是非文本数据的不同表示。
    【解决方案2】:

    你可以使用这个库,它支持 UUID 和 Dates https://github.com/dakrone/cheshire

    根据项目页面“Cheshire 是快速 JSON 编码,基于 clj-json 和 clojure-json,具有 Date/UUID/Set/Symbol 编码和 SMILE 支持等附加功能。”

    【讨论】:

    • 这是更好的答案。
    【解决方案3】:

    时间戳是一个没有“格式”的对象。您可以选择自己格式化为文本或使用例如cheshire 生成 JSON。 Cheshire 知道哪种日期格式适合 JSON,并且可以进行转换。

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

    Clojure 打印机知道如何向人类表示二进制对象:

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

    您可以自己选择文本表示:

    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"
    

    为了区分清楚,对象也可以用字节值表示,是无损的:

    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)
    

    【讨论】:

      【解决方案4】:

      对于日期和时间,最好只使用 clj-time,它是 joda 时间库的包装器。这避免了处理令人讨厌的 java 日期、时间日历、格式的东西。

      我最近在 github 上也看到了一个 clj-uuid 库,这可能会使使用 uuid 变得更简单

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-07
        • 1970-01-01
        • 2012-06-14
        • 2011-09-08
        • 1970-01-01
        相关资源
        最近更新 更多