Open1

Cloud Workflowメモ

karupanerurakarupanerura

日本の休日を判定する

checkHoliday:
    params: []
    steps:
    - init:
        assign:
            - now: ${time.format(sys.now(), "Asia/Tokyo")}
            - year: ${int(text.substring(now, 0, 4))}
            - month: ${int(text.substring(now, 5, 7))}
            - day: ${int(text.substring(now, 8, 10))}
    - calculateWeekDay:
        assign:
            - year: ${if(month <= 2, year-1, year)}
            - month: ${if(month <= 2, month+12, month)}
            - weekDay: ${(year + year//4 - year//100 + year//400 + (13*month+8)//5 + day) % 7}
    - checkWeekEnd:
        switch:
            - condition: ${weekDay == 0 or weekDay == 6}
              next: isWeekEnd
        next: callListEvents
    - isWeekEnd:
        return: true
    - callListEvents:
        try:
            call: http.get
            args:
                url: 'https://www.googleapis.com/calendar/v3/calendars/ja.japanese%23holiday%40group.v.calendar.google.com/events'
                query:
                    timeMin: '${time.format(sys.now()//86400*86400)}'
                    timeMax: '${time.format(sys.now()//86400*86400+86400)}'
                    timeZone: Asia/Tokyo
                auth:
                    type: OAuth2
                    scopes: https://www.googleapis.com/auth/calendar.readonly
            result: res
        retry: ${http.default_retry}
    - result:
        return: ${len(res.body.items) != 0}

解説

init stepでは日本のAsia/Tokyoのタイムゾーンでフォーマットした時刻の文字列から text.substring で年月日を抜き出し、 int 型に変換している。フォーマットされる形式が固定的でかつ年月日の各セクションまでが固定長であるため、こういうことをやっても安全。
calculateWeekDay stepでは、ツェラーの公式を使って曜日を計算している。現在時刻しか扱わない前提なので、グレゴリオ暦しか対応していない。除算に / ではなく // を使ってint型として結果を求めるのがキモ。
callListEvents はGoogle Calendar公式の日本の休日カレンダーを取得している。今日ぶんのレンジに絞って取得して、なんかしらエントリがあったら祝日という寸法。(どれくらいうまくいくのかはまだちゃんと試していない)

その他には特に難しいところはないと思うので割愛。