2013-07-09 12 views
13

E 'facile da leggere una data letterale:Come stampare tempo come #inst

(read-string "#inst \"2012\"") 
     ;;; ⇒ #inst "2012-01-01T00:00:00.000-00:00" 

come posso uscita una data come #inst... letterale?

Questo non funziona:

(pr-str (clj-time.core/now)) 
     ;;; ⇒ "#<DateTime 2013-07-09T17:26:30.058Z>" 

(read-string (pr-str (clj-time.core/now))) 
     ;;; ⇒ <err> 
     ;;; RuntimeException Unreadable form clojure.lang.Util.runtimeException (Util.java:219) 
+0

Sto usando clojure 1.5.1, inserendo quanto segue in REPL '(java.util.Date.)' Prints '#inst" 2013-07-09T18: 05: 53.231-00: 00 "'. –

+0

Si noti che 'clj-time.core/now' è un oggetto DateTime, che è Joda. – Jeremy

+0

Oh, capisco, mio ​​errore. Grazie :). Che ne dici di convertire 'DateTime' in' java.util.Date' e poi stamparlo? –

risposta

11

Quando si legge in un #inst letterale, per impostazione predefinita, viene creata un'istanza java.util.Date. Questi hanno un metodo definito per print-method (un multimetodo responsabile per le rappresentazioni stampate di oggetti) nello spazio dei nomi clojure.instant (il frammento rilevante della sorgente 1.5.1 è here).

clj-time utilizza il tipo DateTime da Joda-Time, che non ha un metodo personalizzato print-method impostato. Questo ha senso, dal momento che avere uno print-method che produce una rappresentazione che non è andata a buon fine è raramente desiderabile. Per poter effettuare il round-trip, dovresti utilizzare un lettore non standard #inst. A tal fine, se stai leggendo i dati EDN, è possibile utilizzare clojure.edn/read (o read-string) passando il lettore appropriato come documentato nella sua docstring:

(require '[clojure.edn :as edn]) 

(edn/read {:readers {'inst your-inst-reader}} rdr) 

Quando si utilizza CLJ-tempo, your-inst-reader sarà qualcosa di simile #(clj-time.format/parse some-formatter %) . È quindi possibile fornire una definizione print-method corrispondente all'esempio di clojure.instant. (Oppure si potrebbe semplicemente fornire la definizione print-method e ricordare che non si otterrà il roundtropping perfetto; clj-time fornisce funzioni di coercizione molto convenienti - vedi sotto - quindi potrebbe essere ok)

In alternativa è possibile stampare e leggere le istanze java.util.Date e convertirle in e da DateTime s; ci sono funzioni per farlo in clj-time.coerce.

+0

Ho finito per forzare a java.util.Date. –

+1

Ho chiesto a monte se è possibile fornire una soluzione generale: https://github.com/clj-time/clj-time/issues/93 – Jacob

+0

Aspetta, quindi come faccio a stampare un timestamp come '#inst" AAAA-MM ... "'? –