Back
in (clj)
(source)protocol
(in dt zone)
Set a date-time to be in a time-zone
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])))
(extend-protocol p/ITimeSpan
; as required by some tests in this ns
Instant
(beginning [i] i)
(end [i] i))
(deftest time-construction-test
(testing "(time)"
(is (t/time? (t/time))))
(testing "(midnight)"
(is (t/time? (t/midnight)))
(is (= "00:00" (str (t/midnight)))))
(testing "(noon)"
(is (t/time? (t/noon)))
(is (= "12:00" (str (t/noon))))))
(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))))))))
(deftest clock-test
(testing "clock"
(t/with-clock (-> (t/date "2018-02-14") (t/at "10:00") (t/in "America/New_York"))
(testing "(clock) return type"
(is (t/clock? (t/clock))))
(testing "Time shifting the clock back by 2 hours"
(is (= "2018-02-14T13:00:00Z" (str (t/instant (t/<< (t/clock) (t/new-duration 2 :hours)))))))
(testing "with instant"
(is (= (t/zone (t/clock (t/instant)))
(t/zone "America/New_York"))))))
(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 "Creating a clock with a zone, and returning that zone"
(is (= "America/New_York" (str (t/zone (t/clock (t/zone "America/New_York")))))))
(testing "Creation of clock with fixed instant"
(is (= "2017-10-31T16:00:00Z" (str (t/instant (t/clock (t/instant "2017-10-31T16:00:00Z")))))))
(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 constructor-test
(is (t/year? (t/year 2017)))
(is (= 2017 (cljc.java-time.year/get-value (t/year 2017))))
(is (t/month? (t/month 12)))
(is (= t/DECEMBER (t/month 12)))
(is (= (t/new-date 3030 3 3)
(t/date "3030-03-03")))
(is (-> (t/new-duration 1000 :millis)
(t/inst)
(t/instant)
(cljc.java-time.instant/to-epoch-milli)
(= 1000)))
(is (= (t/new-year-month 2020 7)
(t/year-month "2020-07"))))
(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 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))))))))
(deftest formatting-test
(testing "all predefined formatters exist"
(doseq [pre-defined (vals t/predefined-formatters)]
(is pre-defined)))
(let [d "3030-05-03"]
(is (= d (t/format :iso-local-date (t/date d))))
(is (= d (t/format (t/formatter :iso-local-date) (t/date d))))
(is (= d (t/format (t/formatter "YYYY-MM-dd") (t/date d))))
#?(:bb
; bb only inlcludes the English Locale by default
(is (= "3030-May-03" (t/format (t/formatter "YYYY-MMM-dd" java.util.Locale/FRENCH)
(t/date d))))
:clj
(is (= "3030-mai-03" (t/format (t/formatter "YYYY-MMM-dd" java.util.Locale/FRENCH)
(t/date d)))))))
(deftest epoch-test
(is (= (cljc.java-time.instant/parse "1970-01-01T00:00:00Z") (t/epoch))))
(deftest addition-test
(is (= (t/new-duration 5 :seconds) (t/+ (t/new-duration 2 :seconds) (t/new-duration 3 :seconds))))
(is (= (t/new-duration 2 :minutes) (t/+ (t/new-duration 90 :seconds) (t/new-duration 30 :seconds)))))
(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))))))
(deftest range-test
(is (t/midnight? (t/beginning (t/today))))
(is (t/midnight? (t/end (t/today))))
(is (t/midnight? (t/beginning (t/year))))
(is (t/midnight? (t/end (t/year)))))
;; 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 comparison-test
(let [point (t/truncate (t/instant) :millis)
later (t/>> point (t/new-duration 1 :millis))]
(testing "shifting inst"
(let [i (t/inst)]
(is (= i (-> i
(t/>> (t/new-duration 10 :seconds))
(t/<< (t/new-duration 10 :seconds)))))))
(testing "max-min"
(is (= later (t/max point later point later)))
(is (= point (t/min point later point later))))
(testing "max-min key"
(is (= {:foo later} (t/max-key :foo {:foo point} {:foo later} {:foo point} {:foo later})))
(is (= {:foo point} (t/min-key :foo {:foo point} {:foo later} {:foo point} {:foo later}))))
(testing "comparables not="
(doseq [point (point-in-time-comparable point)]
(testing "comparables ="
(is (apply t/= point (point-in-time-comparable point)))
(is (apply t/>= point (point-in-time-comparable point))))
(is (apply t/<= point (point-in-time-comparable later))))
(doseq [later (point-in-time-comparable later)]
(is (apply t/>= later (point-in-time-comparable point))))
(doseq [point (point-in-time-comparable point)
later (point-in-time-comparable later)]
(is (t/<= point later))
(is (t/< point later))
(is (t/>= later point))
(is (t/> later point)))))
(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)))))
(testing "durations"
(is (t/> (t/new-duration 20 :seconds) (t/new-duration 10 :seconds)))
(is (t/>= (t/new-duration 20 :seconds) (t/new-duration 20 :seconds)))
(is (t/>= (t/new-duration 20 :seconds) (t/new-duration 19 :seconds)))
(is (not (t/>= (t/new-duration 19 :seconds) (t/new-duration 20 :seconds))))
(is (t/< (t/new-duration 10 :seconds) (t/new-duration 20 :seconds)))
(is (t/<= (t/new-duration 20 :seconds) (t/new-duration 20 :seconds)))
(is (t/<= (t/new-duration 19 :seconds) (t/new-duration 20 :seconds)))
(is (not (t/<= (t/new-duration 20 :seconds) (t/new-duration 19 :seconds))))))
(deftest comparison-test-date
(let [t1 (t/inst "2019-12-24T00:00:00.000Z")
t2 (t/inst "2019-12-31T00:00:00.000Z")]
(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 day-of-week
(let [days (fn [strings] (map t/day-of-week strings))]
(is (every? #{cljc.java-time.day-of-week/sunday} (days ["sun" "sunday"])))
(is (every? #{cljc.java-time.day-of-week/monday} (days ["mon" "monday"])))
(is (every? #{cljc.java-time.day-of-week/tuesday} (days ["tue" "tues" "tuesday"])))
(is (every? #{cljc.java-time.day-of-week/wednesday} (days ["wed" "weds" "wednesday"])))
(is (every? #{cljc.java-time.day-of-week/thursday} (days ["thur" "thurs" "thursday"])))
(is (every? #{cljc.java-time.day-of-week/friday} (days ["fri" "friday"])))
(is (every? #{cljc.java-time.day-of-week/saturday} (days ["sat" "saturday"])))))
(deftest adjusters
(is (= (t/date "2022-01-15")
(t/day-of-week-in-month (t/date "2022-01-01") 3 t/SATURDAY)))
(is (= (t/date "2022-01-01")
(t/first-in-month (t/date "2022-01-01") t/SATURDAY)))
(is (= (t/date "2022-01-29")
(t/last-in-month (t/date "2022-01-01") t/SATURDAY)))
(is (= (t/date "2022-01-08")
(t/next (t/date "2022-01-01") t/SATURDAY)))
(is (= (t/date "2022-01-01")
(t/next-or-same (t/date "2022-01-01") t/SATURDAY)))
(is (= (t/date "2021-12-25")
(t/previous (t/date "2022-01-01") t/SATURDAY)))
(is (= (t/date "2022-01-01")
(t/previous-or-same (t/date "2022-01-01") t/SATURDAY))))
(deftest month
(let [months (fn [strings] (map t/month strings))]
(is (every? #{cljc.java-time.month/january} (months ["jan" "january"])))
(is (every? #{cljc.java-time.month/february} (months ["feb" "february"])))
(is (every? #{cljc.java-time.month/march} (months ["mar" "march"])))
(is (every? #{cljc.java-time.month/april} (months ["apr" "april"])))
(is (every? #{cljc.java-time.month/may} (months ["may"])))
(is (every? #{cljc.java-time.month/june} (months ["jun" "june"])))
(is (every? #{cljc.java-time.month/july} (months ["jul" "july"])))
(is (every? #{cljc.java-time.month/august} (months ["aug" "august"])))
(is (every? #{cljc.java-time.month/september} (months ["sep" "september"])))
(is (every? #{cljc.java-time.month/october} (months ["oct" "october"])))
(is (every? #{cljc.java-time.month/november} (months ["nov" "november"])))
(is (every? #{cljc.java-time.month/december} (months ["dec" "december"])))))
(is (= (t/of-hours 24) (t/duration (t/date))))
(is (= (t/of-days 1) (t/duration {:tick/beginning (t/date)
:tick/end (t/inc (t/date))}))))
;; Durations. Convenience functions to create durations of specific
;; units.
(deftest duration-functions-test
(is (= (t/of-nanos 10) (t/new-duration 10 :nanos)))
(is (= (t/of-micros 10) (t/new-duration 10 :micros))) ;java.time.Duration doesn't have ofMicros method
(is (= (t/of-millis 10) (t/new-duration 10 :millis)))
(is (= (t/of-seconds 10) (t/new-duration 10 :seconds)))
(is (= (t/of-minutes 10) (t/new-duration 10 :minutes)))
(is (= (t/of-hours 10) (t/new-duration 10 :hours))))
(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])))
(extend-protocol p/ITimeSpan
; as required by some tests in this ns
Instant
(beginning [i] i)
(end [i] i)
LocalDateTime
(beginning [i] i)
(end [i] i))
(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 basic-relations-test
(is (= (count ti/basic-relations) 13))
(is (distinct? ti/basic-relations)))
;; We can construct every possible combination of interval relation with just 4 instants.
(def instants [(t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T13:00:00Z")
(t/instant "2017-07-30T15:00:00Z")])
;; Distinct: because no pair of definite intervals can be related by more than one of the relationships.
;; From [ALSPAUGH-2009]
(deftest distinct-test
(is
(= [1] ; Each interval should have just one relation that is true
(distinct
(let [f (apply juxt ti/basic-relations)]
(for [x1 instants
x2 instants
y1 instants
y2 instants
:when (t/< x1 x2)
:when (t/< y1 y2)
:let [x (ti/new-interval x1 x2)
y (ti/new-interval y1 y2)]]
;; For each combination, count how many relations are true
;; (should be just one each time)
(count (filter true? (f x y)))))))))
;; Exhaustive: because any pair of definite intervals are described by one of the relations.
(deftest exhaustive-test []
(is
(= 13 ; Thirteen basic relations
(count
(distinct
(for [x1 instants
x2 instants
y1 instants
y2 instants
:when (t/< x1 x2)
:when (t/< y1 y2)
:let [x (ti/new-interval x1 x2)
y (ti/new-interval y1 y2)]]
;; For each combination, count how many relations are true
;; (should be just one each time)
(ti/relation x y)))))))
(deftest disjoint-test []
(is (ti/disjoint?
(ti/new-interval (instants 0) (instants 1))
(ti/new-interval (instants 2) (instants 3))))
(is (= (ti/disjoint?
(ti/new-interval (instants 0) (instants 1))
(ti/new-interval (instants 2) (instants 3))) ti/precedes?))
(is (nil?
(ti/disjoint?
(ti/new-interval (instants 0) (instants 2))
(ti/new-interval (instants 1) (instants 3)))))
(is (nil?
(ti/disjoint?
(ti/new-interval (instants 0) (instants 3))
(ti/new-interval (instants 1) (instants 2))))))
;; concur is really the complement to disjoint, but we'll test it
;; anywhere to ensure the complement function is working as expected.
(deftest concur?-test []
(is (nil?
(ti/concur?
(ti/new-interval (instants 0) (instants 1))
(ti/new-interval (instants 2) (instants 3)))))
(is (= (ti/concur?
(ti/new-interval (instants 0) (instants 2))
(ti/new-interval (instants 1) (instants 3)))
ti/overlaps?))
(is (= (ti/concur?
(ti/new-interval (instants 0) (instants 3))
(ti/new-interval (instants 1) (instants 2)))
ti/contains?)))
(deftest concur-test []
(is
(=
(ti/new-interval (instants 1) (instants 2))
(ti/concur
(ti/new-interval (instants 0) (instants 2))
(ti/new-interval (instants 1) (instants 3)))))
(is
(=
(ti/new-interval (instants 1) (instants 2))
(ti/concur
(ti/new-interval (instants 1) (instants 3))
(ti/new-interval (instants 0) (instants 2)))))
(is
(nil?
(ti/concur
(ti/new-interval (instants 0) (instants 1))
(ti/new-interval (instants 2) (instants 3)))))
(is
(nil?
(ti/concur
(ti/new-interval (instants 0) (instants 1))
(ti/new-interval (instants 1) (instants 2)))))
(is
(=
(ti/new-interval (instants 0) (instants 2))
(ti/concur
(ti/new-interval (instants 0) (instants 2))
(ti/new-interval (instants 0) (instants 3)))))
(is
(=
(ti/new-interval (instants 0) (instants 2))
(ti/concur
(ti/new-interval (instants 0) (instants 3))
(ti/new-interval (instants 0) (instants 2)))))
(is
(=
(ti/new-interval (instants 1) (instants 3))
(ti/concur
(ti/new-interval (instants 1) (instants 3))
(ti/new-interval (instants 0) (instants 3)))))
(is
(=
(ti/new-interval (instants 1) (instants 2))
(ti/concur
(ti/new-interval (instants 1) (instants 3))
(ti/new-interval (instants 1) (instants 2))
(ti/new-interval (instants 0) (instants 2)))))
(is
(nil?
(ti/concur
(ti/new-interval (instants 1) (instants 2))
(ti/new-interval (instants 2) (instants 3))
(ti/new-interval (instants 0) (instants 2)))))
(is
(nil?
(ti/concur
(ti/new-interval (instants 0) (instants 1))
(ti/new-interval (instants 1) (instants 2))
(ti/new-interval (instants 2) (instants 3))))))
;; TODO: Support this: (ti/new-interval (t/now) (t/seconds 10))
;; TODO: Don't allow this: (ti/new-interval (t/now)) -- returns an illegal ti/new-interval
(deftest ordered-disjoint-intervals?-test
(is
(ti/ordered-disjoint-intervals? []))
(is
(ti/ordered-disjoint-intervals?
[(ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T10:00:00Z"))]))
(is
(ti/ordered-disjoint-intervals?
[(ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T10:00:00Z"))
(ti/new-interval (t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T13:00:00Z"))]))
(is
(ti/ordered-disjoint-intervals?
[(ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T11:00:00Z"))
(ti/new-interval (t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T13:00:00Z"))]))
(is
(ti/ordered-disjoint-intervals?
[(ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T11:00:00Z"))
(ti/new-interval (t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T13:00:00Z"))
(ti/new-interval (t/instant "2017-07-30T16:00:00Z")
(t/instant "2017-07-30T18:00:00Z"))]))
(is
(false?
(ti/ordered-disjoint-intervals?
[(ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T12:00:00Z"))
(ti/new-interval (t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T13:00:00Z"))])))
(is
(false?
(ti/ordered-disjoint-intervals?
[(ti/new-interval (t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T13:00:00Z"))
(ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T10:00:00Z"))]))))
(deftest unite-test
(testing "Unite meeting intervals"
(is
(=
[(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-30"))]
(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-30"))]]
(ti/unite intervals)))))
(testing "Unite overlapping intervals"
(is
(=
[(ti/new-interval (t/date "2017-06-10") (t/date "2017-06-25"))
(ti/new-interval (t/date "2017-07-01") (t/date "2017-07-10"))]
(map ti/bounds
(ti/unite [(ti/new-interval (t/date "2017-06-10") (t/date "2017-06-20"))
(ti/new-interval (t/date "2017-06-15") (t/date "2017-06-25"))
(ti/new-interval (t/date "2017-07-01") (t/date "2017-07-10"))])))))
(testing "Unite containing intervals"
(is
(=
[(ti/new-interval (t/date "2017-06-15") (t/date "2017-06-25"))]
(map ti/bounds
(ti/unite [(ti/new-interval (t/date "2017-06-15") (t/date "2017-06-25"))
(ti/new-interval (t/date "2017-06-17") (t/date "2017-06-20"))])))))
(testing "Unite finished-by intervals"
(is
(=
[(ti/new-interval (t/date "2017-06-15") (t/date "2017-06-25"))]
(map ti/bounds
(ti/unite [(ti/new-interval (t/date "2017-06-15") (t/date "2017-06-25"))
(ti/new-interval (t/date "2017-06-17") (t/date "2017-06-20"))
(ti/new-interval (t/date "2017-06-18") (t/date "2017-06-25"))]))))))
(deftest flatten-test
(let [ivals [(ti/new-interval (t/date "2017-06-15") (t/date "2017-06-25"))
(ti/new-interval (t/date "2017-06-17") (t/date "2017-06-20"))
(ti/new-interval (t/date "2017-06-18") (t/date "2017-06-25"))
(ti/new-interval (t/date "2017-07-18") (t/date "2017-07-25"))
(ti/new-interval (t/date "2017-08-18") (t/date "2017-08-25"))]]
(is (= ivals (ti/flatten (ti/unite ivals))))))
(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")}]}]
(ti/normalize intervals)))))
(deftest union-test
(testing "counts"
(let [coll1 [(ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T12:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T15:00:00Z"))]
coll3 [(ti/new-interval (t/instant "2017-07-30T17:00:00Z")
(t/instant "2017-07-30T19:00:00Z"))]]
(is (= 1 (count (ti/union coll1 coll2))))
(is (ti/ordered-disjoint-intervals? (ti/union coll1 coll2)))
(is (= 2 (count (ti/union coll1 coll2 coll3))))
(is (ti/ordered-disjoint-intervals? (ti/union coll1 coll2 coll3)))))
(testing "union"
(let [ival1 (ti/new-interval (t/instant "2017-07-30T09:00:00Z")
(t/instant "2017-07-30T10:00:00Z"))
ival2 (ti/new-interval (t/instant "2017-07-30T10:00:00Z")
(t/instant "2017-07-30T11:00:00Z"))
ival3 (ti/new-interval (t/instant "2017-07-30T11:00:00Z")
(t/instant "2017-07-30T12:00:00Z"))
ival4 (ti/new-interval (t/instant "2017-07-30T12:00:00Z")
(t/instant "2017-07-30T13:00:00Z"))
ival5 (ti/new-interval (t/instant "2017-07-30T13:00:00Z")
(t/instant "2017-07-30T14:00:00Z"))
res (ti/union [ival2 ival4] [ival1 ival3 ival5])]
(is (= res [ival1 ival2 ival3 ival4 ival5])))))
(deftest intersection-test
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T06:00:00Z")
(t/instant "2017-01-01T07:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T09:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T09:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T13:00:00Z")
(t/instant "2017-01-01T15:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T17:00:00Z")
(t/instant "2017-01-01T19:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T09:00:00Z")
(t/instant "2017-01-01T10:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T11:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T18:00:00Z"))]]
(is
(= [(ti/new-interval (t/instant "2017-01-01T09:00:00Z") (t/instant "2017-01-01T10:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T11:00:00Z") (t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z") (t/instant "2017-01-01T15:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T17:00:00Z") (t/instant "2017-01-01T18:00:00Z"))]
(ti/intersection coll1 coll2))))
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T16:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T09:00:00Z")
(t/instant "2017-01-01T11:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T13:00:00Z")
(t/instant "2017-01-01T17:00:00Z"))]]
(is
(= [(ti/new-interval (t/instant "2017-01-01T09:00:00Z") (t/instant "2017-01-01T11:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z") (t/instant "2017-01-01T16:00:00Z"))]
(ti/intersection coll1 coll2))))
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T16:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))]]
(is
(=
[(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))]
(ti/intersection coll1 coll2))))
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T17:00:00Z")
(t/instant "2017-01-01T19:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T18:00:00Z"))]]
(is (=
[(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T17:00:00Z")
(t/instant "2017-01-01T18:00:00Z"))]
(ti/intersection coll1 coll2))))
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T12:00:00Z")
(t/instant "2017-01-01T14:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T11:00:00Z")
(t/instant "2017-01-01T14:00:00Z"))]]
(is (= [(ti/new-interval (t/instant "2017-01-01T12:00:00Z")
(t/instant "2017-01-01T14:00:00Z"))]
(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))))
(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)))
(testing "Empty sets"
(let [coll1 []
coll2 [(ti/new-interval (t/instant "2017-01-01T09:00:00Z")
(t/instant "2017-01-01T10:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T11:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T18:00:00Z"))]]
(is
(empty? (ti/intersection coll1 coll2)))
(is
(empty? (ti/intersection coll2 coll1)))
(is
(empty? (ti/intersection [] [])))))))
(deftest difference-test
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T16:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T09:00:00Z")
(t/instant "2017-01-01T11:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T13:00:00Z")
(t/instant "2017-01-01T17:00:00Z"))]]
(is
(= [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T09:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T11:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))]
(ti/difference coll1 coll2))))
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T16:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))]]
(is
(=
[(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T16:00:00Z"))]
(ti/difference coll1 coll2))))
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T17:00:00Z")
(t/instant "2017-01-01T19:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T18:00:00Z"))]]
(is (=
[(ti/new-interval (t/instant "2017-01-01T18:00:00Z")
(t/instant "2017-01-01T19:00:00Z"))]
(ti/difference coll1 coll2))))
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T12:00:00Z")
(t/instant "2017-01-01T14:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T11:00:00Z")
(t/instant "2017-01-01T14:00:00Z"))]]
(is (empty? (ti/difference coll1 coll2))))
(testing "Empty sets"
(let [coll1 []
coll2 [(ti/new-interval (t/instant "2017-01-01T09:00:00Z")
(t/instant "2017-01-01T10:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T11:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T18:00:00Z"))]]
(is
(= []
(ti/difference coll1 coll2)))
(is
(= coll2
(ti/difference coll2 coll1)))
(is
(= []
(ti/difference [] []))))))
(deftest difference-invariant-test
(let [coll1 [(ti/new-interval (t/instant "2017-01-01T14:00:00Z")
(t/instant "2017-01-01T16:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T08:00:00Z")
(t/instant "2017-01-01T12:00:00Z"))]
coll2 [(ti/new-interval (t/instant "2017-01-01T09:00:00Z")
(t/instant "2017-01-01T11:00:00Z"))
(ti/new-interval (t/instant "2017-01-01T13:00:00Z")
(t/instant "2017-01-01T17:00:00Z"))]]
(is
(thrown?
#?(:clj clojure.lang.ExceptionInfo
:cljs ExceptionInfo)
(ti/difference coll1 coll2)))))
;; We are reclaiming 'disjoin' to mean to 'end the joining of' or 'to become disjoint'.
#_(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 complement-test
(testing "complement through max of type"
(is (= [(ti/new-interval (t/time "01:00") (t/max-of-type (t/time "00:00")))]
(ti/complement [(ti/new-interval (t/time "00:00") (t/time "01:00"))]))))
(testing "complement ordered disjoint intervals"
(is (= [(ti/new-interval (t/time "00:00") (t/time "01:00"))
(ti/new-interval (t/time "02:00") (t/time "03:00"))
(ti/new-interval (t/time "04:00") (t/max-of-type (t/time "00:00")))]
(ti/complement [(ti/new-interval (t/time "01:00") (t/time "02:00"))
(ti/new-interval (t/time "03:00") (t/time "04:00"))]))))
(testing "complement meeting intervals"
(is (= [(ti/new-interval (t/time "00:00") (t/time "01:00"))
(ti/new-interval (t/time "03:00") (t/max-of-type (t/time "00:00")))]
(ti/complement [(ti/new-interval (t/time "01:00") (t/time "02:00"))
(ti/new-interval (t/time "02:00") (t/time "03:00"))]))))
(testing "complement empty interval round trip"
(is (= [] (ti/complement (ti/complement []))))))
(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"))])))))
(testing "O"
(is
(=
{(t/year 2015) [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]
(t/year 2016) [(ti/bounds (t/year 2016))]
(t/year 2017) [(ti/bounds (t/year-month "2017-01") (t/year-month "2017-06"))]}
(ti/group-by
(ti/divide (ti/bounds (t/year 2014) (t/year 2018)) t/year)
[(ti/bounds (t/year-month "2015-06") (t/year-month "2017-06"))]))))
(testing "M and e"
(is
(=
{(t/year 2015) [(t/year 2015)]
(t/year 2016) [(t/year 2016)]}
(ti/group-by
(ti/divide (ti/bounds (t/year 2014) (t/year 2017)) t/year)
(ti/divide (ti/bounds (t/year 2015) (t/year 2016)) t/year)))))
(testing "s"
(is (=
{(t/year 2015) [(ti/bounds (t/year 2015))]
(t/year 2016) [(ti/bounds (t/year 2016))]}
(ti/group-by
(ti/divide (ti/bounds (t/year 2014) (t/year 2017)) t/year)
[(ti/bounds (t/year 2015) (t/year 2016))]))))
(testing "f"
(is
(=
{(t/year 2015) [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]}
(ti/group-by
[(t/year 2014) (t/year 2015) (t/year 2016)]
[(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]))))
(testing "F"
(is
(=
{(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))
[(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]}
(ti/group-by
[(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]
[(t/year 2014) (t/year 2015) (t/year 2016)]))))
(testing "d"
(is
(=
{(t/year 2015) [(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))]}
(ti/group-by
[(t/year 2014) (t/year 2015) (t/year 2016)]
[(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))]))))
(testing "D"
(is
(=
{(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))
[(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))]}
(testing "o"
(is
(=
{(ti/bounds (t/year-month "2015-06") (t/year-month "2017-06"))
[(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))
(t/year "2016")
(ti/bounds (t/year-month "2017-01") (t/year-month "2017-06"))]}
(ti/group-by
[(ti/bounds (t/year-month "2015-06") (t/year-month "2017-06"))]
(ti/divide (ti/bounds (t/year 2014) (t/year 2018)) t/year))))))
(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))))))
;; TODO: more Interval testing
(deftest successive-intervals-meet
(doseq [x [(t/date) (t/year) (t/year-month)]]
(is (ti/meets? (t/end x) (t/beginning (t/inc x))))))
(deftest concur-test2
(is
(= 2
(t/hours
(t/duration
(ti/concur (ti/new-interval (t/at (t/today) "16:00")
(t/end (t/today)))
(t/today)
(ti/new-interval (t/at (t/today) "20:00")
(t/at (t/today) "22:00"))))))))
;; Example: We mustn't disturb people between 10pm and 7am the following morning, in their locale.
(defn moment [t]
(ti/new-interval
t
(t/>> t (t/new-duration 3 :seconds))))
;; TODO: Think about conversions between single instants and intervals. Feather? Widen? Smudge?
;; Can we disturb?
(deftest cannot-disturb-test
(extend-protocol p/ITimeSpan
LocalTime
(beginning [i] i)
(end [i] i))
(let
[disturb-interval [(ti/new-interval (t/time "07:00") (t/time "22:00"))]
no-disturb-interval (ti/complement disturb-interval)
can-disturb? (fn [t] (not (some #(t/coincident? % t) no-disturb-interval)))
]
(is (not (can-disturb? (t/time "03:00"))))
(is (not (can-disturb? (t/time "07:00"))))
(is (can-disturb? (t/time "07:01")))
(is (can-disturb? (t/time "12:00")))
(is (can-disturb? (t/time "21:59")))
(is (not (can-disturb? (t/time "22:00"))))
(is (not (can-disturb? (t/time "00:00"))))))
(deftest predicate-test
(is (true? (t/interval? (moment (t/now))))))
tick
(ns tick.internals-test
(:require [clojure.test
:refer [deftest is testing run-tests]
:refer-macros [deftest is testing run-tests]]
[tick.core :as t]
[tick.protocols :as p]))
(deftest parse-test
(testing "(time \"4pm\")"
(is (t/time? (p/parse "4pm")))
(is (= "16:00" (str (p/parse "4pm"))))))