X Tutup
(ns java-time.zone (:require [java-time.core :as jt.c] [java-time.temporal :as jt.t] [java-time.util :as jt.u] [java-time.amount :as jt.a] [java-time.format :as jt.f] [java-time.clock :as jt.clock] [java-time.properties :as jt.p :refer (get-unit-checked)] [java-time.defconversion :refer (conversion! deffactory)]) (:import [java.time.temporal TemporalAccessor] [java.time.format DateTimeFormatter] [java.time Clock Instant LocalDate LocalTime LocalDateTime ZoneId ZoneOffset OffsetDateTime OffsetTime ZonedDateTime])) ;;;;; Zone Id (defn- to-hms [n] (if (integer? n) [n 0 0] (let [h (int n) m-n (* 60 (- n h)) m (int m-n) s (int (* 60 (- m-n m)))] [h m s]))) (conversion! java.util.TimeZone ZoneId (fn [^java.util.TimeZone z] (.toZoneId z))) (conversion! CharSequence ZoneId (fn [^CharSequence s] (ZoneId/of s))) (conversion! [CharSequence ZoneOffset] ZoneId (fn [^CharSequence s, ^ZoneOffset zo] (ZoneId/ofOffset s zo))) (defn- ^ZoneOffset clock->zone-offset [^Clock c] (-> (.getZone c) (.getRules) (.getOffset (.instant c)))) (deffactory zone-offset "Creates a `ZoneOffset` from a string identifier (e.g. \"+01\"), a number of hours/hours and minutes/hours, minutes and seconds or extracts from another temporal entity. Returns default system zone offset if no arguments provided." :returns ZoneOffset :implicit-arities [] ([] (jt.clock/make clock->zone-offset)) ([o] (cond (instance? ZoneOffset o) o (instance? Clock o) (clock->zone-offset o) (instance? java.time.temporal.TemporalAccessor o) (ZoneOffset/from ^java.time.temporal.TemporalAccessor o) (string? o) (ZoneOffset/of ^String o) (number? o) (let [[h m s] (to-hms o)] (zone-offset h m s)) :else (throw (java.time.DateTimeException. (format "Could not convert %s to a ZoneOffset!" o))))) ([h m] (ZoneOffset/ofHoursMinutes h m)) ([h m s] (ZoneOffset/ofHoursMinutesSeconds h m s))) (deffactory zone-id "Creates a `ZoneId` from a string identifier, `java.util.TimeZone` or extracts from another temporal entity. Returns default system zone id if no arguments provided. Given two arguments will use the second as the offset." :returns ZoneId :implicit-arities [1 2] ([] (jt.clock/make (fn [^Clock c] (.getZone c))))) (defn available-zone-ids "Returns a set of string identifiers for all available ZoneIds." [] (ZoneId/getAvailableZoneIds)) ;; offset date/time (deffactory offset-date-time "Creates an `OffsetDateTime`. The following arguments are supported: * no arguments - current date-time with the default offset * one argument + clock + zone offset + another temporal entity + string representation + year * two arguments + formatter (format) and a string + local date-time and an offset + another temporal entity and an offset (preserves local time) + year and month * three arguments + local date, local time and an offset + year, month and date * four up to seven arguments - position date-time constructors * eight arguments - time fields up to nanoseconds and a zone offset If zone offset is not specified, default will be used. You can check the default offset by invoking `(zone-offset)`." :returns OffsetDateTime :implicit-arities [1 2 3] ([] (jt.clock/make (fn [^Clock c] (OffsetDateTime/now c)))) ([y m d h] (offset-date-time y m d h 0)) ([y mo d h m] (offset-date-time y mo d h m 0)) ([y mo d h m s] (offset-date-time y mo d h m s 0)) ([y mo d h m s n] (offset-date-time y mo d h m s n (zone-offset))) ([y mo d h m s n o] (OffsetDateTime/of (int (jt.c/value y)) (int (jt.c/value mo)) (int (jt.c/value d)) (int h) (int m) (int s) (int n) (zone-offset o)))) (deffactory offset-time "Creates an `OffsetTime`. The following arguments are supported: * no arguments - current time with the default offset * one argument + clock + zone id + another temporal entity + string representation + hour * two arguments + formatter (format) and a string + local time and an offset + instant and an offset + hour and minutes * three arguments - hours, minutes, seconds * four arguments - hours, minutes, seconds, nanos * five arguments - last is the offset If zone offset is not specified, default will be used. You can check the default offset by invoking `(zone-offset)`." :returns OffsetTime :implicit-arities [1 2] ([] (jt.clock/make (fn [^Clock c] (OffsetTime/now c)))) ([h m s] (offset-time h m s 0)) ([h m s n] (offset-time h m s n (zone-offset))) ([h m s n o] (OffsetTime/of h m s n (zone-offset o)))) (deffactory zoned-date-time "Creates a `ZonedDateTime`. The following arguments are supported: * no arguments - current date-time in the default zone * one argument + clock + zone id + another temporal entity + string representation + year * two arguments + formatter and a string + local date-time and a zone id + year and month * three arguments + local date, local time and a zone id + year, month and day * four to seven arguments - date-time fields * eight arguments - last is the zone id If zone id is not specified, default zone id will be used. You can check the default zone by invoking `(zone-id)`." :returns ZonedDateTime :implicit-arities [1 2 3] ([] (jt.clock/make (fn [^Clock c] (ZonedDateTime/now c)))) ([y m d h] (zoned-date-time y m d h 0)) ([y mo d h m] (zoned-date-time y mo d h m 0)) ([y mo d h m s] (zoned-date-time y mo d h m s 0)) ([y mo d h m s n] (zoned-date-time y mo d h m s n (zone-id))) ([y mo d h m s n o] (ZonedDateTime/of (int (jt.c/value y)) (int (jt.c/value mo)) (int (jt.c/value d)) (int h) (int m) (int s) (int n) (zone-id o)))) (conversion! Clock ZonedDateTime (fn [^Clock c] (ZonedDateTime/now c))) (conversion! Clock OffsetDateTime (fn [^Clock c] (OffsetDateTime/now c))) (conversion! Clock OffsetTime (fn [^Clock c] (OffsetTime/now c))) (conversion! ZoneId ZonedDateTime (fn [^ZoneId z] (jt.clock/make (fn [^Clock c] (ZonedDateTime/now (.withZone c z))))) 2) (conversion! ZoneId OffsetDateTime (fn [^ZoneId z] (jt.clock/make (fn [^Clock c] (OffsetDateTime/now (.withZone c z))))) 2) (conversion! ZoneId OffsetTime (fn [^ZoneId z] (jt.clock/make (fn [^Clock c] (OffsetTime/now (.withZone c z))))) 2) (conversion! CharSequence ZonedDateTime (fn [^CharSequence s] (ZonedDateTime/parse s)) 2) (conversion! CharSequence OffsetDateTime (fn [^CharSequence s] (OffsetDateTime/parse s)) 2) (conversion! CharSequence OffsetTime (fn [^CharSequence s] (OffsetTime/parse s)) 2) (conversion! ZonedDateTime [Instant ZoneId] (fn [^ZonedDateTime zdt] [(.toInstant zdt) (.getZone zdt)])) (conversion! OffsetDateTime [Instant ZoneOffset] (fn [^OffsetDateTime odt] [(.toInstant odt) (.getOffset odt)])) (conversion! OffsetTime [LocalTime ZoneOffset] (fn [^OffsetTime odt] [(.toLocalTime odt) (.getOffset odt)])) (conversion! OffsetTime OffsetDateTime (fn [^OffsetTime ot] (.atDate ot (LocalDate/now))) 2) (conversion! [LocalDateTime ZoneOffset] OffsetDateTime (fn [^LocalDateTime ldt, ^ZoneOffset zo] (OffsetDateTime/of ldt zo))) (conversion! [LocalDateTime ZoneId] ZonedDateTime (fn [^LocalDateTime ldt, ^ZoneId z] (ZonedDateTime/of ldt z))) (conversion! [LocalTime ZoneOffset] OffsetTime (fn [^LocalTime lt, ^ZoneOffset zo] (OffsetTime/of lt zo))) (conversion! [Instant ZoneId] ZonedDateTime (fn [^Instant i, ^ZoneId z] (ZonedDateTime/ofInstant i z))) (conversion! [Instant ZoneId] OffsetDateTime (fn [^Instant i, ^ZoneId z] (OffsetDateTime/ofInstant i z))) (conversion! [Instant ZoneId] OffsetTime (fn [^Instant i, ^ZoneId z] (OffsetTime/ofInstant i z))) (conversion! [java.time.format.DateTimeFormatter CharSequence] ZonedDateTime #(ZonedDateTime/from (jt.f/parse %1 %2))) (conversion! [java.time.format.DateTimeFormatter CharSequence] OffsetDateTime #(OffsetDateTime/from (jt.f/parse %1 %2))) (conversion! [java.time.format.DateTimeFormatter CharSequence] OffsetTime #(OffsetTime/from (jt.f/parse %1 %2))) (conversion! Number ZonedDateTime (fn [value] (zoned-date-time value 1 1 0))) (conversion! Number OffsetDateTime (fn [value] (offset-date-time value 1 1 0))) (conversion! Number OffsetTime (fn [value] (offset-time value 0 0))) (conversion! [Number Number] ZonedDateTime (fn [y m] (zoned-date-time y m 1 0))) (conversion! [Number Number] OffsetDateTime (fn [y m] (offset-date-time y m 1 0))) (conversion! [Number Number] OffsetTime (fn [h m] (offset-time h m 0))) (conversion! [Number Number Number] ZonedDateTime (fn [y m d] (zoned-date-time y m d 0))) (conversion! [Number Number Number] OffsetDateTime (fn [y m d] (offset-date-time y m d 0))) (jt.u/when-class "java.util.GregorianCalendar" (conversion! java.util.GregorianCalendar ZonedDateTime (fn [^java.util.GregorianCalendar cal] (.toZonedDateTime cal)))) (defprotocol HasOffset (with-offset [o offset] "Sets the offset to the specified value ensuring that the local time stays the same. (offset-time 10 30 0 0 +2) => # (with-offset *1 +3) => #") (with-offset-same-instant [o offset] "Sets the offset to the specified value ensuring that the result has the same instant, e.g.: (offset-time 10 30 0 0 +2) => # (with-offset-same-instant *1 +3) => #")) (extend-type OffsetDateTime jt.c/Truncatable (truncate-to [o u] (.truncatedTo o (get-unit-checked u))) HasOffset (with-offset [o offset] (.withOffsetSameLocal o (zone-offset offset))) (with-offset-same-instant [o offset] (.withOffsetSameInstant o (zone-offset offset))) jt.c/Ordered (single-after? [d o] (.isAfter d o)) (single-before? [d o] (.isBefore d o))) (extend-type OffsetTime jt.c/Truncatable (truncate-to [o u] (.truncatedTo o (get-unit-checked u))) HasOffset (with-offset [o offset] (.withOffsetSameLocal o (zone-offset offset))) (with-offset-same-instant [o offset] (.withOffsetSameInstant o (zone-offset offset))) jt.c/Ordered (single-after? [d o] (.isAfter d o)) (single-before? [d o] (.isBefore d o))) (extend-type ZonedDateTime jt.c/Truncatable (truncate-to [o u] (.truncatedTo o (get-unit-checked u))) jt.c/HasZone (with-zone [o z] (.withZoneSameLocal o (zone-id z)))) (defn with-zone-same-instant "Sets the zone to the specified value ensuring that the result has the same instant, e.g.: (zoned-date-time 2015) => # (with-zone-same-instant *1 \"America/New_York\") => #" [^ZonedDateTime zdt, z] (.withZoneSameInstant zdt (zone-id z))) ;;;;; Clock (defn ^java.time.Clock system-clock "Creates a system clock. In the default time zone if called without arguments, otherwise accepts a Zone Id." ([] (Clock/systemDefaultZone)) ([k] (Clock/system (zone-id k)))) (defn ^java.time.Clock fixed-clock "Creates a fixed clock either at the current instant or at the supplied instant/instant + zone." ([] (Clock/fixed (Instant/now) (zone-id))) ([i] (Clock/fixed (jt.t/instant i) (zone-id))) ([i z] (Clock/fixed (jt.t/instant i) (zone-id z)))) (defn ^java.time.Clock offset-clock "Creates a clock offset from the current/provided clock by a given `duration`." ([d] (Clock/offset (system-clock) (jt.a/duration d))) ([^Clock c, d] (Clock/offset c (jt.a/duration d)))) (defn ^java.time.Clock tick-clock "Creates a clock wrapping system/provided clock that only ticks as per specified duration." ([d] (Clock/tick (system-clock) (jt.a/duration d))) ([^Clock c, d] (Clock/tick c (jt.a/duration d)))) (defn clock? "Returns true if `x` is an instance of `java.time.Clock`." [x] (instance? Clock x)) (extend-type Clock jt.c/ReadableProperty (value [c] (.millis c)) jt.c/HasZone (with-zone [c z] (.withZone c (zone-id z))) jt.c/Ordered (single-after? [c o] (> (.millis c) (.millis ^Clock o))) (single-before? [c o] (< (.millis c) (.millis ^Clock o)))) ;; Avoid cyclic dep (extend-type java.time.format.DateTimeFormatter jt.c/HasZone (with-zone [dtf zone] (.withZone dtf (zone-id zone))))
X Tutup