Back
date-time (clj)
(source)protocol
(date-time _)
Make a java.time.LocalDateTime instance.
Examples
tick
(ns tick.api-test
(:require
[clojure.test
:refer [deftest is testing run-tests]
:refer-macros [deftest is testing run-tests]]
[tick.core :as t]
[tick.locale-en-us]
[tick.protocols :as p]
[cljc.java-time.clock]
[cljc.java-time.instant]
[cljc.java-time.day-of-week]
[cljc.java-time.month]
[cljc.java-time.year]
#?@(:cljs [[java.time :refer [Instant]]]))
#?(:clj
(:import [java.time Instant])))
(deftest date-construction-test
(is (= (t/date "2018-01-11")
(t/date (t/instant 1515691416624))))
(is (t/date-time? (t/noon (t/today))))
(t/with-clock (-> (t/date "2018-02-14") (t/at "10:00"))
(testing "(noon (today))"
(is (= "2018-02-14T12:00" (str (t/noon (t/today))))))
(testing "(noon (date))"
(is (= "2018-02-14T12:00" (str (t/noon (t/date))))))))
(testing "Converting using with-clock"
(t/with-clock (t/clock (t/zone "America/New_York"))
(testing "inst to zoned-date-time"
(is (t/= (t/zoned-date-time "2019-08-07T16:00Z")
(t/zoned-date-time "2019-08-07T12:00-04:00[America/New_York]"))))
(testing "date-time to zoned-date-time"
(is (t/= (t/zoned-date-time (t/date-time "2019-08-07T12:00"))
(t/zoned-date-time "2019-08-07T12:00-04:00[America/New_York]"))))
(testing "date-time to offset-date-time"
(is (t/= (t/offset-date-time (t/date-time "2019-08-07T12:00"))
(t/offset-date-time "2019-08-07T12:00-04:00"))))))
(testing "Creation of clock with fixed offset"
(is (= "+01:00" (str (t/zone (t/clock (t/offset-date-time "2017-10-31T16:00:00+01:00"))))))))
(deftest extraction-test
(is (= 2 (t/int t/FEBRUARY)))
(is (= 2 (t/int t/TUESDAY)))
(is (= t/AUGUST (t/month (t/date-time "2017-08-08T12:00:00"))))
(is (= t/AUGUST (t/month (t/year-month "2017-08"))))
(is (= (t/year 2019) (t/year (t/zoned-date-time "2019-09-05T00:00:00+02:00[Europe/Oslo]"))))
(is (= (t/year 2019) (t/year (t/offset-date-time "2019-09-05T00:00:00-03:00"))))
(is (= (t/zone-offset "-04:00")
(t/zone-offset (t/zoned-date-time "2019-03-15T15:00-04:00[America/New_York]"))))
(is (= (t/zone-offset "-04:00")
(t/zone-offset (t/offset-date-time "2019-03-15T15:00-04:00")))))
;; Point-in-time tests
(deftest today-test
(t/with-clock (cljc.java-time.clock/fixed (t/instant "2017-08-08T12:00:00Z") t/UTC)
(is (= (t/instant "2017-08-08T12:00:00Z") (t/now)))
(is (= (t/date "2017-08-08") (t/today)))
(is (= (t/date "2017-08-07") (t/yesterday)))
(is (= (t/date "2017-08-09") (t/tomorrow)))
(is (= 8 (t/day-of-month (t/today))))
(is (= 2017 (t/int (t/year))))
(is (= (t/date-time "2017-08-08T12:00:00") (t/noon (t/today))))
(is (= (t/date-time "2017-08-08T00:00:00") (t/midnight (t/today))))))
(deftest instant-test
(testing "instant basics"
(is (t/instant? (t/instant (t/now))))
(is (t/instant? (t/instant (str cljc.java-time.instant/min))))
(is (t/instant? (t/instant (t/zoned-date-time))))))
(deftest offset-date-time-test
(let [t "2018-09-24T18:57:08.996+01:00"]
(testing "offset date time basics"
(is (t/offset-date-time? (t/offset-date-time (t/now))))
(is (t/offset-date-time? (t/offset-date-time t)))
(is (t/offset-date-time? (t/offset-date-time (t/date-time))))
(is (t/offset-date-time? (t/offset-date-time (t/zoned-date-time)))))))
(deftest zoned-date-time-test
(is (t/zoned-date-time? (t/zoned-date-time "2020-12-15T12:00:10Z[Europe/London]")))
(is (t/zoned-date-time? (t/zoned-date-time "2020-12-15T12:00:10+04:00[Europe/London]"))))
(deftest fields-test
(let [xs [(t/now)
(t/zoned-date-time)
(t/offset-date-time)
(t/date-time)
(t/date)
(t/time)
(t/year)
(t/year-month)]]
(doseq [x xs]
(let [fields (t/fields x)
fields-map (into {} fields)]
(is (not-empty fields-map))
(doseq [[f v] fields-map]
(is (= v (get fields f)))
(is (= :foo (get fields :bar :foo))))))))
(let [now (t/instant)
from (t/<< now (t/new-duration 10 :seconds))
to (t/>> now (t/new-duration 10 :seconds))]
(is (= (t/new-duration 20 :seconds) (t/between from to) ))
(is (= 20 (t/between from to :seconds))))
(is
(= (t/new-duration 48 :hours)
(t/between (t/beginning (t/today)) (t/end (t/tomorrow)))))
(let [start (t/date-time "2020-01-01T12:00")
end (t/date-time "2020-01-01T12:02")]
(is
(=
(t/new-duration 2 :minutes)
(t/between start end))
(= 2 (t/between start end :minutes))))
(is
(=
(t/new-duration 30 :minutes)
(t/between (t/new-time 11 0 0) (t/new-time 11 30 0))))
(testing "LocalDate"
(let [start (t/date "2020-01-01")
end (t/date "2020-01-02")]
(is (= (t/new-period 1 :days)
(t/between start end)))
(is (= 1 (t/between start end :days))))))
;; Comparison test
(defn point-in-time-comparable [i]
[i
(t/inst i)
(t/zoned-date-time i)
(t/offset-date-time i)])
(deftest truncate-test
(let [dates [(t/instant) (t/zoned-date-time) (t/date-time)
(t/offset-date-time) (t/time)]
truncate-tos [:nanos
:micros
:millis
:seconds
:minutes
:hours
:half-days
:days ]]
(doseq [date dates
truncate-to truncate-tos]
(is (t/truncate date truncate-to)))))
(deftest parse-test
(is (t/date? (t/parse-date "2020/02/02" (t/formatter "yyyy/MM/dd"))))
(is (t/year? (t/parse-year "20" (t/formatter "yy"))))
(is (t/year-month? (t/parse-year-month "20/02" (t/formatter "yy/MM"))))
(is (t/date-time? (t/parse-date-time "2020/02/02:2002" (t/formatter "yyyy/MM/dd:HHmm"))))
(is (t/time? (t/parse-time "2002" (t/formatter "HHmm"))))
(is (t/zoned-date-time? (t/parse-zoned-date-time "2020/02/02:2002:Z"
(t/formatter "yyyy/MM/dd:HHmm:VV"))))
(is (t/offset-date-time? (t/parse-offset-date-time "2020/02/02:2002:-08:30"
(t/formatter "yyyy/MM/dd:HHmm:VV")))))
(testing "ZonedDateTimes in different zones should be equals"
(is (t/=
(t/zoned-date-time "2017-10-31T16:00:00-04:00[America/New_York]")
(t/zoned-date-time "2017-10-31T13:00:00-07:00[America/Los_Angeles]"))))
(testing "ZoneDateTimes and OffsetDateTime should be equals if represents the same point in time"
(is (t/=
(t/zoned-date-time "2017-10-31T16:00:00-04:00[America/New_York]")
(t/offset-date-time "2017-10-31T13:00-07:00"))))
(testing "ZoneDateTimes and platform Date should be equals if represents the same point in time"
(is (t/=
(t/zoned-date-time "2017-10-31T16:00:00-04:00[America/New_York]")
(t/inst "2017-10-31T20:00:00Z"))))
(testing "Instants and ZonedDateTimes should be equals if represents the same point in time"
(is (t/=
(t/instant (t/clock (t/instant "2017-10-31T16:00:00Z")))
(t/zoned-date-time "2017-10-31T16:00:00Z[UTC]"))))
(is
(t/<
(t/now)
(t/>> (t/now) (t/new-duration 10 :seconds))
(t/>> (t/now) (t/new-duration 20 :seconds))))
(is
(t/>
(t/>> (t/now) (t/new-duration 20 :seconds))
(t/>> (t/now) (t/new-duration 10 :seconds))
(t/now)))
(is (not
(t/<
(t/now)
(t/>> (t/now) (t/new-duration 20 :seconds))
(t/>> (t/now) (t/new-duration 10 :seconds)))))
(let [at (t/now)]
(is (t/<= at at (t/>> at (t/new-duration 1 :seconds))))
(is (t/>= at at (t/<< at (t/new-duration 10 :seconds)))))
(deftest coincidence-test
(let [int-beginning (t/instant "2020-02-02T00:00:00Z")
int-end (t/>> int-beginning (t/of-hours 2))
interval {:tick/beginning int-beginning
:tick/end int-end}]
(is (t/coincident? interval (t/>> int-beginning (t/of-hours 1))))
(is (not (t/coincident? interval (t/<< int-beginning (t/of-hours 1)))))
(is (t/coincident? interval int-beginning))
(is (t/coincident? interval int-end))
(is (t/coincident? interval interval))
(is (not (t/coincident? interval (-> interval
(update :tick/end #(t/>> % (t/of-nanos 1))))))))
(testing "non-interval coincidence"
(doseq [[start-f new-amount] [[t/date t/of-days] [t/date-time t/of-hours]]]
(let [start (start-f)
end (t/>> start (new-amount 2))]
(is (t/coincident? start end (t/>> start (new-amount 1))))
(is (not (t/coincident? start end (t/<< start (new-amount 1)))))
(is (t/coincident? start end start))
(is (t/coincident? start end end))))))
(deftest predicates-test
(is (true? (t/clock? (t/clock))))
(is (true? (t/day-of-week? t/MONDAY)))
(is (true? (t/duration? (t/new-duration 1 :minutes))))
(is (true? (t/instant? (t/instant))))
(is (true? (t/date? (t/today))))
(is (true? (t/date-time? (t/at (t/today) (t/new-time 0 0)))))
(is (true? (t/time? (t/new-time 0 0))))
(is (true? (t/month? t/MAY)))
(is (true? (t/offset-date-time? (t/offset-date-time))))
(is (true? (t/period? (t/new-period 1 :weeks))))
(is (true? (t/year? (t/year))))
(is (true? (t/year-month? (t/year-month))))
(is (true? (t/zone? (t/zone))))
(is (true? (t/zone-offset? (t/zone-offset (t/zoned-date-time)))))
(is (true? (t/zoned-date-time? (t/zoned-date-time))))
(is (false? (t/date? 16)))
(is (false? (t/month? 16))))
(deftest in-test
(is (= (t/zoned-date-time "2021-04-23T11:23:24.576270-04:00[America/Toronto]")
(t/in (t/instant "2021-04-23T15:23:24.576270Z")
(t/zone "America/Toronto"))))
(is (= (t/zoned-date-time "2021-04-23T11:18:46.594720-04:00[America/Toronto]")
(t/in (t/offset-date-time "2021-04-23T13:18:46.594720-02:00")
(t/zone "America/Toronto"))))
(is (= (t/zoned-date-time "2021-04-23T11:18:46.594720-04:00[America/Toronto]")
(t/in (t/zoned-date-time "2021-04-23T08:18:46.594720-07:00[America/Los_Angeles]")
(t/zone "America/Toronto")))))
tick
(ns tick.alpha.interval-test
(:require
[clojure.spec.alpha :as s]
[tick.core :as t]
[tick.protocols :as p]
[clojure.test
:refer [deftest is testing run-tests]
:refer-macros [deftest is testing run-tests]]
[tick.alpha.interval :as ti]
#?@(:cljs [[java.time :refer [Instant LocalDateTime LocalTime]]]))
#?(:clj
(:import [java.time LocalDateTime Instant LocalTime])))
(deftest date-relation-test
(is (=
(ti/relation
(ti/new-interval
(t/zoned-date-time "2021-02-24T00:00Z[GMT]")
(t/zoned-date-time "2021-02-25T00:00Z[GMT]"))
(ti/new-interval
(t/zoned-date-time "2021-02-23T00:00Z[Europe/London]")
(t/zoned-date-time "2021-02-24T00:00Z[Europe/London]")))
:met-by)))
(deftest normalize-test
(let [intervals
[(ti/new-interval (t/date "2017-06-15") (t/date "2017-06-25"))
(ti/new-interval (t/date "2017-06-26") (t/date "2017-06-28"))
(ti/new-interval (t/date "2017-06-30") (t/date "2017-07-04"))]]
(is (= [{:tick/intervals
[{:tick/beginning (t/date-time "2017-06-15T00:00")
:tick/end (t/date-time "2017-06-26T00:00")}
{:tick/beginning (t/date-time "2017-06-26T00:00")
:tick/end (t/date-time "2017-06-29T00:00")}]}
{:tick/intervals
[{:tick/beginning (t/date-time "2017-06-30T00:00")
:tick/end (t/date-time "2017-07-05T00:00")}]}]
(let [coll1 [(ti/new-interval (t/date-time "2017-04-11T00:00")
(t/date-time "2017-04-14T00:00"))
(ti/new-interval (t/date-time "2017-04-18T00:00")
(t/date-time "2017-04-20T00:00"))
(ti/new-interval (t/date-time "2017-12-20T00:00")
(t/date-time "2017-12-23T00:00"))
(ti/new-interval (t/date-time "2017-12-27T00:00")
(t/date-time "2018-01-01T00:00"))
(ti/new-interval (t/date-time "2018-01-02T00:00")
(t/date-time "2018-01-08T00:00"))]
coll2 [(ti/bounds (t/year "2017"))]]
(is (= [(ti/new-interval (t/date-time "2017-04-11T00:00")
(t/date-time "2017-04-14T00:00"))
(ti/new-interval (t/date-time "2017-04-18T00:00")
(t/date-time "2017-04-20T00:00"))
(ti/new-interval (t/date-time "2017-12-20T00:00")
(t/date-time "2017-12-23T00:00"))
(ti/new-interval (t/date-time "2017-12-27T00:00")
(t/date-time "2018-01-01T00:00"))]
(ti/intersection coll1 coll2))))
(let [coll1 [(ti/new-interval (t/date-time "2017-04-11T00:00")
(t/date-time "2017-04-14T00:00"))
(ti/new-interval (t/date-time "2017-04-18T00:00")
(t/date-time "2017-04-20T00:00"))
(ti/new-interval (t/date-time "2017-12-20T00:00")
(t/date-time "2017-12-23T00:00"))
(ti/new-interval (t/date-time "2017-12-27T00:00")
(t/date-time "2018-01-01T00:00"))
(ti/new-interval (t/date-time "2018-01-02T00:00")
(t/date-time "2018-01-08T00:00"))]
coll2 [(ti/bounds (t/year "2017"))]]
(is (= [(ti/new-interval (t/date-time "2017-04-11T00:00")
(t/date-time "2017-04-14T00:00"))
(ti/new-interval (t/date-time "2017-04-18T00:00")
(t/date-time "2017-04-20T00:00"))
(ti/new-interval (t/date-time "2017-12-20T00:00")
(t/date-time "2017-12-23T00:00"))
(ti/new-interval (t/date-time "2017-12-27T00:00")
(t/date-time "2018-01-01T00:00"))]
(ti/intersection coll1 coll2)))
#_(deftest disj-test
(is (=
[(ti/new-interval (t/date-time "2017-01-01T00:00")
(t/date-time "2017-07-04T00:00"))
(ti/new-interval (t/date-time "2017-07-05T00:00")
(t/date-time "2018-01-01T00:00"))]
(disj [(bounds "2017")] (bounds (t/date "2017-07-04"))))))
(deftest group-by-intervals-test
(testing "p and s"
(t/with-clock t/UTC
(is
(=
{(t/year 2017) [(ti/new-interval
(t/date-time "2017-12-20T00:00")
(t/date-time "2018-01-01T00:00"))]
(t/year 2018) [(ti/new-interval
(t/date-time "2018-01-01T00:00")
(t/date-time "2018-01-10T00:00"))]}
(ti/group-by
(ti/divide (ti/bounds (t/year 2016) (t/year 2019)) t/year)
[(ti/new-interval (t/date-time "2017-12-20T00:00")
(t/date-time "2018-01-10T00:00"))])))))
(deftest am-test
(t/with-clock (cljc.java-time.clock/fixed (t/instant "2017-08-08T12:00:00Z") t/UTC)
(is (= (ti/new-interval (t/date-time "2017-08-08T00:00:00")
(t/date-time "2017-08-08T12:00:00"))
(ti/am (t/today))))
(is (= (ti/new-interval (t/date-time "2017-08-08T12:00:00")
(t/date-time "2017-08-09T00:00:00"))
(ti/pm (t/today))))))
(deftest division-test2
(is (= 365 (count (ti/divide-by t/date (t/year 2017)))))
(is (= 12 (count (ti/divide-by t/year-month (t/year 2017)))))
(is (= 30 (count (ti/divide-by t/date (t/year-month "2017-09")))))
(is (= (t/date "2017-09-01") (first (ti/divide-by t/date (t/year-month "2017-09")))))
(is (= (t/date "2017-09-30") (last (ti/divide-by t/date (t/year-month "2017-09")))))
(is (= 31 (count (ti/divide-by t/date (t/year-month "2017-10")))))
(is (= 8 (count (ti/divide-by t/date (ti/bounds (t/date "2017-10-03") (t/date "2017-10-10"))))))
(is (= [(t/date "2017-09-10")] (ti/divide-by t/date (ti/bounds (t/date-time "2017-09-10T12:00")
(t/date-time "2017-09-10T14:00")))))
(is (= [(t/date "2017-09-10") (t/date "2017-09-11")] (ti/divide-by t/date (ti/bounds (t/date-time "2017-09-10T12:00") (t/date-time "2017-09-11T14:00")))))
(is (= 2 (count (ti/divide-by t/year-month (ti/bounds (t/date "2017-09-10") (t/date "2017-10-10"))))))
(is (= 3 (count (ti/divide-by t/year (ti/bounds (t/date-time "2017-09-10T12:00") (t/year "2019"))))))
(is (= 3 (count (ti/divide-by t/year (ti/bounds (t/date-time "2017-09-10T12:00") (t/year-month "2019-02"))))))
(is (= 24 (count (ti/divide-by (t/new-duration 1 :hours) (t/date "2017-09-10"))))))