Skip to content

Commit

Permalink
Merge pull request clj-time#12 from r0man/coerce-protocol
Browse files Browse the repository at this point in the history
Coerce protocol
  • Loading branch information
seancorfield committed Feb 12, 2012
2 parents 8abfdab + bff7e15 commit 1179403
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 34 deletions.
90 changes: 68 additions & 22 deletions src/clj_time/coerce.clj
Original file line number Diff line number Diff line change
@@ -1,53 +1,99 @@
(ns clj-time.coerce
"Utilites to coerce Joda DateTime instances to and from various other types.
For example, to convert a Joda DateTime to and from a Java long:
=> (to-long (date-time 1998 4 25))
893462400000
=> (from-long 893462400000)
#<DateTime 1998-04-25T00:00:00.000Z>"
(:refer-clojure :exclude [extend])
(:use clj-time.core)
(:require [clj-time.format :as time-fmt])
(:import (org.joda.time DateTime DateTimeZone))
(:import java.util.Date))
(:import java.util.Date java.sql.Timestamp))

(defn to-long
"Returns the number of milliseconds that the given DateTime is after Unix
epoch."
[#^DateTime dt]
(.getMillis dt))
(defprotocol ICoerce
(to-date-time [obj] "Convert `obj` to a Joda DateTime instance."))

(defn from-long
"Returns a DateTime instance in the UTC time zone corresponding to the given
number of milliseconds after the Unix epoch."
[#^Long millis]
(DateTime. millis #^DateTimeZone utc))
[#^Long millis]
(DateTime. millis #^DateTimeZone utc))

(defn from-string
"return DateTime instance from string using
formatters in clj-time.format, returning first
which parses"
[s]
(first
(for [f (vals time-fmt/formatters)
:let [d (try (time-fmt/parse f s) (catch Exception _ nil))]
:when d] d)))

(defn to-date
"Returns a Java Date object corresponding to the given DateTime instance."
[#^DateTime dt]
(Date. #^Long (to-long dt)))
(for [f (vals time-fmt/formatters)
:let [d (try (time-fmt/parse f s) (catch Exception _ nil))]
:when d] d)))

(defn from-date
"Returns a DateTime instance in the UTC time zone corresponding to the given
Java Date object."
[#^Date date]
(from-long (.getTime date)))

(defn to-long
"Convert `obj` to the number of milliseconds after the Unix epoch."
[obj]
(if-let [dt (to-date-time obj)]
(.getMillis dt)))

(defn to-date
"Convert `obj` to a Java Date instance."
[obj]
(if-let [dt (to-date-time obj)]
(Date. (.getMillis dt))))

(defn to-string
"Returns a string representation of date in UTC time-zone using
(ISODateTimeFormat/dateTime) date-time representation. "
[#^DateTime dt]
(time-fmt/unparse (:date-time time-fmt/formatters) dt))
"Returns a string representation of obj in UTC time-zone
using (ISODateTimeFormat/dateTime) date-time representation."
[obj]
(if-let [dt (to-date-time obj)]
(time-fmt/unparse (:date-time time-fmt/formatters) dt)))

(defn to-timestamp
"Convert `obj` to a Java SQL Timestamp instance."
[obj]
(if-let [dt (to-date-time obj)]
(Timestamp. (.getMillis dt))))

(extend-type nil
ICoerce
(to-date-time [_]
nil))

(extend-type Date
ICoerce
(to-date-time [date]
(from-date date)))

(extend-type DateTime
ICoerce
(to-date-time [date-time]
date-time))

(extend-type Integer
ICoerce
(to-date-time [integer]
(from-long (long integer))))

(extend-type Long
ICoerce
(to-date-time [long]
(from-long long)))

(extend-type String
ICoerce
(to-date-time [string]
(from-string string)))

(extend-type Timestamp
ICoerce
(to-date-time [timestamp]
(from-date timestamp)))
72 changes: 60 additions & 12 deletions test/clj_time/coerce_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,72 @@
(:refer-clojure :exclude [extend])
(:use clojure.test)
(:use (clj-time core coerce))
(:import java.util.Date))
(:import java.util.Date java.sql.Timestamp))

(deftest test-to-long
(is (= 893462400000 (to-long (date-time 1998 4 25)))))

(deftest test-from-long
(is (= (date-time 1998 4 25) (from-long 893462400000))))

(deftest test-to-from-date
(deftest test-from-date
(let [dt (from-long 893462400000)
d (to-date dt)]
(is (instance? Date d))
(is (= dt (from-date d)))))

(deftest test-to-string
(is (= (to-string (date-time 1998 4 25))
"1998-04-25T00:00:00.000Z")))
(deftest test-from-long
(is (= (date-time 1998 4 25) (from-long 893462400000))))

(deftest test-from-string
(is (= (from-string "1998-04-25T00:00:00.000Z")
(date-time 1998 4 25))))
(date-time 1998 4 25))))

(deftest test-to-date
(is (nil? (to-date nil)))
(is (nil? (to-date "")))
(is (nil? (to-date "x")))
(is (= (Date. 893462400000) (to-date (date-time 1998 4 25))))
(is (= (Date. 893462400000) (to-date (Date. 893462400000))))
(is (= (Date. (long 0)) (to-date 0)))
(is (= (Date. 893462400000) (to-date 893462400000)))
(is (= (Date. 893462400000) (to-date (Timestamp. 893462400000))))
(is (= (Date. 893462400000) (to-date "1998-04-25T00:00:00.000Z"))))

(deftest test-to-date-time
(is (nil? (to-date-time nil)))
(is (nil? (to-date-time "")))
(is (nil? (to-date-time "x")))
(is (= (date-time 1998 4 25) (to-date-time (date-time 1998 4 25))))
(is (= (date-time 1998 4 25) (to-date-time (Date. 893462400000))))
(is (= (date-time 1970 1 1) (to-date-time 0)))
(is (= (date-time 1998 4 25) (to-date-time 893462400000)))
(is (= (date-time 1998 4 25) (to-date-time (Timestamp. 893462400000))))
(is (= (date-time 1998 4 25) (to-date-time "1998-04-25T00:00:00.000Z"))))

(deftest test-to-long
(is (nil? (to-long nil)))
(is (nil? (to-long "")))
(is (nil? (to-long "x")))
(is (= 893462400000 (to-long (date-time 1998 4 25))))
(is (= 893462400000 (to-long (Date. 893462400000))))
(is (= (long 0) (to-long 0)))
(is (= 893462400000 (to-long 893462400000)))
(is (= 893462400000 (to-long (Timestamp. 893462400000))))
(is (= 893462400000 (to-long "1998-04-25T00:00:00.000Z"))))

(deftest test-to-string
(is (nil? (to-string nil)))
(is (nil? (to-string "")))
(is (nil? (to-string "x")))
(is (= "1998-04-25T00:00:00.000Z" (to-string (date-time 1998 4 25))))
(is (= "1998-04-25T00:00:00.000Z" (to-string (Date. 893462400000))))
(is (= "1970-01-01T00:00:00.000Z" (to-string 0)))
(is (= "1998-04-25T00:00:00.000Z" (to-string 893462400000)))
(is (= "1998-04-25T00:00:00.000Z" (to-string (Timestamp. 893462400000))))
(is (= "1998-04-25T00:00:00.000Z" (to-string "1998-04-25T00:00:00.000Z"))))

(deftest test-to-timestamp
(is (nil? (to-timestamp nil)))
(is (nil? (to-timestamp "")))
(is (nil? (to-timestamp "x")))
(is (= (Timestamp. 893462400000) (to-timestamp (date-time 1998 4 25))))
(is (= (Timestamp. 893462400000) (to-timestamp (Date. 893462400000))))
(is (= (Timestamp. (long 0)) (to-timestamp 0)))
(is (= (Timestamp. 893462400000) (to-timestamp 893462400000)))
(is (= (Timestamp. 893462400000) (to-timestamp (Timestamp. 893462400000))))
(is (= (Timestamp. 893462400000) (to-timestamp "1998-04-25T00:00:00.000Z"))))

0 comments on commit 1179403

Please sign in to comment.