アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

隙があればlispを詰め込んで行きたい (6)

非常にどうでも良い理由で今日が祝日であるかどうかを判定したくなりました。
休日の判定は思ったより色々面倒そうですが、動機がどうでも良いことだけに簡単に済ませたいところ。
ということで、休日情報のAPIが公開されていないか調べたところ、いくつかみつかったのですが、Google Calendarからjsonで手軽に情報を取得できるようなので、これを使ってみることにしました。

(DEFUN GET-CALENDAR-JSON (UT)
  (LET ((REQUEST-URL
         (KMRCL:MAKE-URL
          "full"
          :BASE-DIR "http://www.google.com/calendar/feeds/japanese@holiday.calendar.google.com/public/"
          :VARS `(("start-min" . ,(XYZZY:FORMAT-DATE-STRING "%Y-%m-%d" UT))
                  ("start-max" . ,(XYZZY:FORMAT-DATE-STRING
                                   "%Y-%m-%d"
                                   (+ UT (* 24 60 60))))
                  ("max-results" . "1")
                  ("alt" . "json-in-script")
                  ("callback" . "handleJson")))))
    (STRING-TRIM "handleJson();"
                 (SB-EXT:OCTETS-TO-STRING
                  (DRAKMA:HTTP-REQUEST REQUEST-URL :FORCE-BINARY 'T)))))

(DEFUN -> (LIST &REST KEYS)
  (IF (ENDP KEYS)
      LIST
      (KMRCL:AWHEN (FIND (CAR KEYS) LIST :KEY #'ZL:CAR-SAFE)
        (APPLY #'-> KMRCL:IT (CDR KEYS)))))

(DEFUN HOLIDAY-P (&OPTIONAL (UT (GET-UNIVERSAL-TIME)))
  (LET ((DAY (NTH-VALUE 6 (DECODE-UNIVERSAL-TIME UT))))
    (OR (<= 5 DAY)
        (< 0
           (CDR
            (-> (JSON:DECODE-JSON-FROM-STRING (GET-CALENDAR-JSON UT))
                :FEED
                :OPEN-SEARCH$TOTAL-RESULTS
                :$T))))))
(HOLIDAY-P)
;⇒ 今日が休日ならT

(HOLIDAY-P (ENCODE-UNIVERSAL-TIME 0 0 0 21 7 2010))
;⇒ NIL

(HOLIDAY-P (ENCODE-UNIVERSAL-TIME 0 0 0 19 7 2010))
;⇒ T

どうやらGoogle Calendarだと今年分しか情報が取得できない様子なのですが、当日が休日なのかどうかを判定できさえすれば良いのでこれでOKとします。