java8 の java.time.* 関連
;;; java.time.Local* -> java.sql.*
(java.sql.Date/valueOf (java.time.LocalDate/now)) ;; => #inst "2016-06-22T15:00:00.000-00:00"
(-> (java.time.Instant/now) .toEpochMilli java.sql.Date.);; => #inst "2016-06-23T13:25:55.577-00:00"
(java.sql.Time/valueOf (java.time.LocalTime/now)) ;; => #inst "1970-01-01T13:22:01.000-00:00"
(-> (java.time.Instant/now) .toEpochMilli java.sql.Time.) ;; => #inst "2016-06-23T13:25:40.615-00:00"
(java.sql.Timestamp/valueOf (java.time.LocalDateTime/now)) ;; => #inst "2016-06-23T13:22:05.241000000-00:00"
(-> (java.time.Instant/now) .toEpochMilli java.sql.Timestamp.) ;; => #inst "2016-06-23T13:24:59.904000000-00:00"
;;; java.sql.* -> java.time.Local*
(let [ts (java.sql.Timestamp. 0)]
[(.toLocalDateTime ts) (.toInstant ts)])
;; => [#object[java.time.LocalDateTime 0x7dcc3f36 "1970-01-01T09:00"] #object[java.time.Instant 0x3f9e981c "1970-01-01T00:00:00Z"]]
(let [t (java.sql.Time. 0)]
[#_(.toInstant t) ;UnsupportedOperationException
(.toLocalTime t)])
;; => [#object[java.time.LocalTime 0x7373a1e8 "09:00"]]
(let [d (java.sql.Date. 0)]
[#_(.toInstant d) ;UnsupportedOperationException
(.toLocalDate d)])
;; => [#object[java.time.LocalDate 0x23c74418 "1970-01-01"]]
;;; (java.time.LocalDate, java.time.LocalTime) => java.time.LocalDateTime
(let [d (java.time.LocalDate/now)
t (java.time.LocalTime/now)]
(java.time.LocalDateTime/of d t))
;; => #object[java.time.LocalDateTime 0x67edb530 "2016-10-08T08:51:37.782"]
;;; java.time.LocalDateTime => (java.time.LocalDate, java.time.LocalTime)
(let [dt (java.time.LocalDateTime/now)]
[(.toLocalDate dt) (.toLocalTime dt)])
;; => [#object[java.time.LocalDate 0x6052ae93 "2016-10-08"] #object[java.time.LocalTime 0x24bec5b3 "08:51:39.718"]]
(require 'clojure.reflect)
(->> (clojure.reflect/reflect java.time.format.DateTimeFormatter)
:members
(filter #(= (:type %) 'java.time.format.DateTimeFormatter))
(map :name))
(comment
(ISO_LOCAL_TIME
ISO_ORDINAL_DATE
ISO_OFFSET_DATE
ISO_TIME
ISO_LOCAL_DATE_TIME
ISO_INSTANT
RFC_1123_DATE_TIME
ISO_DATE
ISO_WEEK_DATE
ISO_OFFSET_TIME
ISO_LOCAL_DATE
ISO_ZONED_DATE_TIME
ISO_OFFSET_DATE_TIME
ISO_DATE_TIME
BASIC_ISO_DATE ))
(import 'java.time.format.DateTimeFormatter)
(def ^:private t (java.time.ZonedDateTime/now))
(.format t DateTimeFormatter/ISO_LOCAL_TIME ) ; => "20:42:31.072"
(.format t DateTimeFormatter/ISO_ORDINAL_DATE ) ; => "2016-246+09:00"
(.format t DateTimeFormatter/ISO_OFFSET_DATE ) ; => "2016-09-02+09:00"
(.format t DateTimeFormatter/ISO_TIME ) ; => "20:42:31.072+09:00"
(.format t DateTimeFormatter/ISO_LOCAL_DATE_TIME ) ; => "2016-09-02T20:42:31.072"
(.format t DateTimeFormatter/ISO_INSTANT ) ; => "2016-09-02T11:42:31.072Z"
(.format t DateTimeFormatter/RFC_1123_DATE_TIME ) ; => "Fri, 2 Sep 2016 20:42:31 +0900"
(.format t DateTimeFormatter/ISO_DATE ) ; => "2016-09-02+09:00"
(.format t DateTimeFormatter/ISO_WEEK_DATE ) ; => "2016-W35-5+09:00"
(.format t DateTimeFormatter/ISO_OFFSET_TIME ) ; => "20:42:31.072+09:00"
(.format t DateTimeFormatter/ISO_LOCAL_DATE ) ; => "2016-09-02"
(.format t DateTimeFormatter/ISO_ZONED_DATE_TIME ) ; => "2016-09-02T20:42:31.072+09:00[Asia/Tokyo]"
(.format t DateTimeFormatter/ISO_OFFSET_DATE_TIME) ; => "2016-09-02T20:42:31.072+09:00"
(.format t DateTimeFormatter/ISO_DATE_TIME ) ; => "2016-09-02T20:42:31.072+09:00[Asia/Tokyo]"
(.format t DateTimeFormatter/BASIC_ISO_DATE ) ; => "20160902+0900"
(.format (java.time.LocalDate/now) java.time.format.DateTimeFormatter/BASIC_ISO_DATE ) ; => "20160827"
(set-env! :dependencies '[[org.clojure/tools.macro "0.1.2"]])
(require '[clojure.tools.macro :refer :all])
;;; http://qiita.com/tag1216/items/91a471b33f383981bfaa
;;; http://qiita.com/tag1216/items/9cb33a39a6666983491d
(def classes
[java.time.LocalDate
java.time.LocalTime
java.time.LocalDateTime
java.time.chrono.JapaneseDate
java.time.OffsetDateTime
java.time.ZonedDateTime
java.time.Instant])
;;; current time
(macrolet [(map-now [xs]
(mapv (fn [x] `(. ~(if (symbol? x) (resolve x) x)
now))
(if (symbol? xs) (var-get (resolve xs)) xs)))]
(map-now classes))
;;; accessors
(macrolet [(map-bean [xs]
(mapv (fn [x] `(bean (. ~(if (symbol? x) (resolve x) x)
now)))
(if (symbol? xs) (var-get (resolve xs)) xs)))]
(map-bean classes))
;;; make specific time
(bean (java.time.LocalTime/of 1 2 3))
;; => {:class java.time.LocalTime, :hour 1, :minute 2, :nano 0, :second 3}
;;; truncate
(bean (.truncatedTo (java.time.LocalTime/now) java.time.temporal.ChronoUnit/SECONDS))
;; => {:class java.time.LocalTime, :hour 14, :minute 49, :nano 0, :second 11}
(bean (.truncatedTo (java.time.LocalTime/now) java.time.temporal.ChronoUnit/MINUTES))
;; => {:class java.time.LocalTime, :hour 14, :minute 48, :nano 0, :second 0}
(bean (.truncatedTo (java.time.LocalTime/now) java.time.temporal.ChronoUnit/HOURS))
;; => {:class java.time.LocalTime, :hour 14, :minute 0, :nano 0, :second 0}
;;; modification
(-> (java.time.LocalTime/of 1 2 3)
(.minusHours 1)
(.plusMinutes 10)
(.plusSeconds 30)
(.plusNanos 50)
bean)
;; => {:class java.time.LocalTime, :hour 0, :minute 12, :nano 50, :second 33}
;;; type conversion
;; with java.util.Date
(let [instant (.toInstant (java.util.Date.))
zone (java.time.ZoneId/systemDefault)]
(java.time.LocalDateTime/ofInstant instant zone)
[
;; (java.time.LocalDate/ofInstant instant zone); No matching method
;; (java.time.LocalTime/ofInstant instant zone); No matching method
(java.time.LocalDateTime/ofInstant instant zone)
;; (java.time.chrono.JapaneseDate/ofInstant instant zone) ; No matching method
(java.time.OffsetDateTime/ofInstant instant zone)
(java.time.ZonedDateTime/ofInstant instant zone)])
;; java.time.*
(let [t (java.time.LocalDateTime/now)]
[(.atZone t (java.time.ZoneId/systemDefault))
(.atOffset t (java.time.ZoneOffset/ofHours 9))
(.toInstant t java.time.ZoneOffset/UTC)])
;; [#object[java.time.ZonedDateTime 0x5aee0f99 "2016-06-23T15:01:33.378+09:00[Asia/Tokyo]"]
;; #object[java.time.OffsetDateTime 0x363f2e36 "2016-06-23T15:01:33.378+09:00"]
;; #object[java.time.Instant 0x102138e6 "2016-06-23T15:01:33.378Z"]]
;;; formatting
;;; https://docs.oracle.com/javase/jp/8/docs/api/java/time/format/DateTimeFormatter.html#predefined
(let [f (java.time.format.DateTimeFormatter/ofPattern "yyyy/MM/dd HH:mm:ss")
t (java.time.LocalDateTime/parse "2015/12/15 23:30:59" f)]
[t (.format t f)])
;; => [#object[java.time.LocalDateTime 0xcc237ff "2015-12-15T23:30:59"] "2015/12/15 23:30:59"]
(let [d (java.time.LocalDate/of 2015 5 1)
f (.. (java.time.format.DateTimeFormatterBuilder.)
(appendPattern "yyyy/MM/dd(E) ")
(appendLiteral "第")
(appendValue (.weekOfMonth (java.time.temporal.WeekFields/of java.time.DayOfWeek/MONDAY 1)))
(appendLiteral "週")
toFormatter)]
(->> (range 10)
(map #(.format (.plusDays d %) f))))
;; ("2015/05/01(金) 第1週"
;; "2015/05/02(土) 第1週"
;; "2015/05/03(日) 第1週"
;; "2015/05/04(月) 第2週"
;; "2015/05/05(火) 第2週"
;; "2015/05/06(水) 第2週"
;; "2015/05/07(木) 第2週"
;; "2015/05/08(金) 第2週"
;; "2015/05/09(土) 第2週"
;; "2015/05/10(日) 第2週")
(let [d (java.time.LocalDate/of 2015 5 1)
f (.. (java.time.format.DateTimeFormatterBuilder.)
(appendPattern "yyyy/MM/dd(E) ")
(appendLiteral "第")
(appendValue (.weekOfMonth (java.time.temporal.WeekFields/of java.time.DayOfWeek/MONDAY 7)))
(appendLiteral "週")
toFormatter)]
(->> (range 10)
(map #(.format (.plusDays d %) f))))
;; ("2015/05/01(金) 第0週"
;; "2015/05/02(土) 第0週"
;; "2015/05/03(日) 第0週"
;; "2015/05/04(月) 第1週"
;; "2015/05/05(火) 第1週"
;; "2015/05/06(水) 第1週"
;; "2015/05/07(木) 第1週"
;; "2015/05/08(金) 第1週"
;; "2015/05/09(土) 第1週"
;; "2015/05/10(日) 第1週")
;;; time zone & offset
(= (java.time.ZoneId/getAvailableZoneIds)
(java.time.ZoneOffset/getAvailableZoneIds)) ; => true
(java.time.ZoneId/systemDefault);; => #object[java.time.ZoneRegion 0x6b89dc2e "Asia/Tokyo"]
(java.time.ZoneId/of "Asia/Tokyo");; => #object[java.time.ZoneRegion 0x7249738f "Asia/Tokyo"]
(.normalized (java.time.ZoneId/of "Asia/Tokyo"));; => #object[java.time.ZoneRegion 0x3fcc7e48 "Asia/Tokyo"]
(.getId (java.time.ZoneId/of "Asia/Tokyo"));; => "Asia/Tokyo"
;; (java.time.ZoneId/from java.time.temporal.TemporalAccessor)
;; (java.time.ZoneId/from (java.time.chrono.JapaneseDate/now))
;; java.time.ZoneOffset
(java.time.ZoneOffset/of "Z");; => #object[java.time.ZoneOffset 0x2d7a4f03 "Z"]
(java.time.ZoneOffset/of "+1");; => #object[java.time.ZoneOffset 0x32edee77 "+01:00"]
(java.time.ZoneOffset/of "-1");; => #object[java.time.ZoneOffset 0x6bf36499 "-01:00"]
(java.time.ZoneOffset/of "+01:00");; => #object[java.time.ZoneOffset 0x32edee77 "+01:00"]
(java.time.ZoneOffset/of "-01:00") ;; => #object[java.time.ZoneOffset 0x6bf36499 "-01:00"]
(java.time.ZoneOffset/ofHours 3);; => #object[java.time.ZoneOffset 0x1269359a "+03:00"]
;; (java.time.ZoneOffset/of "foo") ;; => error
;;; constants
java.time.ZoneOffset/UTC ;;=> #object[java.time.ZoneOffset 0x2d7a4f03 "Z"]
java.time.ZoneOffset/MAX ;;=> #object[java.time.ZoneOffset 0x662ca71d "+18:00"]
java.time.ZoneOffset/MIN ;;=> #object[java.time.ZoneOffset 0xaf31fdf "-18:00"]
;;; alias
java.time.ZoneOffset/SHORT_IDS
;; => {"CTT" "Asia/Shanghai", "ART" "Africa/Cairo", "CNT" "America/St_Johns", "PRT" "America/Puerto_Rico", "PNT" "America/Phoenix", "PLT" "Asia/Karachi", "AST" "America/Anchorage", "BST" "Asia/Dhaka", "CST" "America/Chicago", "EST" "-05:00", "HST" "-10:00", "JST" "Asia/Tokyo", "IST" "Asia/Kolkata", "AGT" "America/Argentina/Buenos_Aires", "NST" "Pacific/Auckland", "MST" "-07:00", "AET" "Australia/Sydney", "BET" "America/Sao_Paulo", "PST" "America/Los_Angeles", "ACT" "Australia/Darwin", "SST" "Pacific/Guadalcanal", "VST" "Asia/Ho_Chi_Minh", "CAT" "Africa/Harare", "ECT" "Europe/Paris", "EAT" "Africa/Addis_Ababa", "IET" "America/Indiana/Indianapolis", "MIT" "Pacific/Apia", "NET" "Asia/Yerevan"}
;;; http://d.hatena.ne.jp/nowokay/20130917
(.. (java.time.ZoneId/of "Asia/Tokyo") getRules isFixedOffset) ;; => false
(.. (java.time.ZoneId/of "UTC") getRules isFixedOffset) ;; => true
(->> (java.time.ZoneId/of "Asia/Tokyo")
.getRules
.getTransitions
(map str))
;; ("Transition[Overlap at 1888-01-01T00:18:59+09:18:59 to +09:00]"
;; "Transition[Gap at 1948-05-02T02:00+09:00 to +10:00]"
;; "Transition[Overlap at 1948-09-11T02:00+10:00 to +09:00]"
;; "Transition[Gap at 1949-04-03T02:00+09:00 to +10:00]"
;; "Transition[Overlap at 1949-09-10T02:00+10:00 to +09:00]"
;; "Transition[Gap at 1950-05-07T02:00+09:00 to +10:00]"
;; "Transition[Overlap at 1950-09-09T02:00+10:00 to +09:00]"
;; "Transition[Gap at 1951-05-06T02:00+09:00 to +10:00]"
;; "Transition[Overlap at 1951-09-08T02:00+10:00 to +09:00]")
(let [now (java.time.LocalDate/now)
now-1 (.minusDays now 1)]
[(.isAfter now now-1)
(.isBefore now now-1)
(.isEqual now now-1)])
;; => [true false false]