2013年1月25日金曜日

Clojure(java)で日付を扱う

Clojure(Java)で日付を扱うには、java.util.Date、java.util.Calendar、java.text.SimpeDateFormatなどを使えば良さそうです。

;;; リテラル
#inst "2013-01-24"
;; => #inst "2013-01-24T00:00:00.000-00:00"
#inst "2013-01-24T00:00:00Z"
;; => #inst "2013-01-24T00:00:00.000-00:00"
(type #inst "2013-01-24")
;; => java.util.Date


;;; 文字列 => java.util.Date
(java.util.Date. "2013/01/24")
;; => #inst "2013-01-23T15:00:00.000-00:00"
(java.util.Date. "2013/01/24 01:02:03")
;; => #inst "2013-01-23T16:02:03.000-00:00"

(def date-format
  (doto (java.text.SimpleDateFormat. "yyyy/MM/dd hh:mm:ss")
    (.setTimeZone (java.util.TimeZone/getTimeZone "UTC"))))

(.parse date-format "2013/01/24 01:02:03")
;; => #inst "2013-01-24T01:02:03.000-00:00"

(-> (doto (java.text.SimpleDateFormat. "yyyy/MM/dd hh:mm:ss")
      (.setTimeZone (java.util.TimeZone/getTimeZone "JST")))
    (.parse "2013/01/24 01:02:03"))
;; => #inst "2013-01-23T16:02:03.000-00:00"


;;; java.util.Date => 文字列
(.format date-format (.parse date-format "2013/01/24 01:02:03"))
;; => "2013/01/24 01:02:03"

;;; UNIX time (1970/01/01 00:00:00 をエポックとする通算秒)
(defn date->unixtime [d]
  (long (/ (.getTime d) 1000)))

(date->unixtime (.parse date-format "1970/01/01 00:00:01"))
;; => 1
(date->unixtime (.parse date-format "1970/01/02 00:00:00"))
;; => 86400

;;; java.util.Date => java.util.Calendar
(defn date->calendar [d]
  (doto (java.util.Calendar/getInstance)
    (.setTime d)))

(date->calendar (.parse date-format "2013/01/24 00:00:00"))
;; => #inst "2013-01-24T09:00:00.000+09:00"
(type (date->calendar (.parse date-format "2013/01/24 00:00:00")))
;; => java.util.GregorianCalendar

;;; 1日毎の日にちのシーケンス
(defn day-seq [day-from]
  (let [c (date->calendar day-from)]
    (lazy-seq
     (cons day-from
           (repeatedly #(do (.add c java.util.Calendar/DAY_OF_YEAR 1)
                            (.getTime c)))))))

(take 3 (day-seq (.parse date-format "2013/01/24 01:02:03")))
;; => (#inst "2013-01-24T01:02:03.000-00:00"
;;     #inst "2013-01-25T01:02:03.000-00:00"
;;     #inst "2013-01-26T01:02:03.000-00:00")

その他、Clojure用のライブラリとして clj-time というのがあるようです。

0 件のコメント:

コメントを投稿