andrewmcveigh / cljs-time

A clj-time inspired date library for clojurescript.
342 stars 57 forks source link

Add transit serialisers #15

Open andrewmcveigh opened 9 years ago

danielcompton commented 9 years ago

This might be a starting point: https://gist.github.com/Deraen/eb3f650c472fb1abe970#file-transit-cljc

pangloss commented 9 years ago
(def transit-verbose-format (ftime/formatter "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))

(deftype VerboseDateHandler []
  Object
  (tag [_ v] "t")
  (rep [_ v] (str (ftime/unparse transit-verbose-format (to-utc v)) "Z"))
  (stringRep [h v] (.rep h v)))

(deftype DateHandler []
  Object
  (tag [_ v] "m")
  (rep [_ v] (.valueOf v))
  (stringRep [h v] (str (.rep h v)))
  (getVerboseHandler [_ v] (VerboseDateHandler.)))

(def date-read-handlers
  {"m" #(ms->date (if (number? %) % (js/parseInt %)))
   "t" #(to-local (ftime/parse transit-verbose-format %))})

(def date-write-handlers
  {UtcDateTime (DateHandler.)
   DateTime (DateHandler.)})
danielcompton commented 9 years ago

; (In cljs) :date-time is faster than using :basic-date-time ; good.date.UtcDateTime.fromIsoString is MUCH faster than either ; For a random data set, transit/read: ; :basic-date-time 1.24sec ; :date-time 700ms ; good.date.UtcDateTime.fromIsoString 70ms

https://gist.github.com/Deraen/eb3f650c472fb1abe970#file-transit-cljc-L8-L13

It might be better to go with native goog.date functions for performance here.

pangloss commented 9 years ago

Agreed that the goog.date native parsers are better. The code I pasted works well but I haven't tried to performance optimize it.

andrewmcveigh commented 9 years ago

Thanks for this.

I guess I've never needed these, so I've been a bit lazy about getting around to it.

danielcompton commented 9 years ago

I've worked on this recently, so I'll put a PR together once I'm happy with our changes.

andrewmcveigh commented 9 years ago

Cool, appreciated! :smiley:

stuarth commented 8 years ago

@danielcompton any chance you have a PR ready? :smile:

danielcompton commented 8 years ago

Hey, I don't have the headspace/time to put together a proper PR for this, but here's the code that we're using:

Clojure:

(ns my.ns
  (:require [cognitect.transit :as transit]])
  (:import [org.joda.time DateTime ReadableInstant]))

(def transit-writers {:handlers {DateTime (transit/write-handler
                                            (constantly "m")
                                            (fn [v] (-> ^ReadableInstant v .getMillis))
                                            (fn [v] (-> ^ReadableInstant v .getMillis .toString)))}})

(def transit-readers {:handlers {"m" (transit/read-handler
                                       (fn [s] (DateTime. (Long/parseLong s))))}})

ClojureScript

(ns my.ns
  (:require [cognitect.transit :as transit])
  (:import [goog.date UtcDateTime]))

(def transit-readers
  {:handlers
   {"m" (transit/read-handler (fn [s] (UtcDateTime.fromTimestamp s)))}})

(def transit-writers
  {:handlers
   {UtcDateTime (transit/write-handler
                  (constantly "m")
                  (fn [v] (.getTime v))
                  (fn [v] (str (.getTime v))))}})

(def packer (sente-transit/->TransitPacker :json transit-writers transit-readers))

Happy for someone to take this and run with it. Some credit also goes to http://increasinglyfunctional.com/2014/09/02/custom-transit-writers-clojure-joda-time/

theronic commented 6 years ago

Thansk, @danielcompton. Any idea how to make timestamps work with sort-by,(sort-by :some/time coll)?

danielcompton commented 6 years ago

I would expect it to work fine after requiring cljs-time.extend?