ポンコツエンジニアのごじゃっぺ開発日記。

いろいろポンコツだけど、気にするな。エンジニアの日々の開発などの記録を残していきます。 自動で収入を得られるサービスやシステムを作ることが目標!!

【GAS】祝日を取得するスクリプトを書いてAPIとして公開してみよう。

この記事は GAS道場 Advent Calendar 2019 のN日目の記事です。 Google Apps Script(GAS)をこれから使おうという方向けのアドベントカレンダーになります。

今回は、指定した日付・期間内の祝日を取得するスクリプトを作成しようと思います。 各言語で例えばPHPだったりC#だったりGolangだったりとで祝日を求めるときはいつも調べちゃいます。そして、良い方法が自分は見つけることができないのです。ただ、GASを使えば、Googleカレンダーとの連携も簡単なので、簡単に祝日を求めることができてしまいます。 また、祝日を取得できるということは、それをAPIとして公開すれば他の言語でも使えるようになってしまうということなのです。

ということで、祝日を取得してAPIとして公開するところまでやってみたいと思います。

はじめに

GASとGoogleカレンダーの連携とはものすごい簡単なものです。

developers.google.com

以下のように書くだけで指定したカレンダーの情報を取得できます。

CalendarApp.getCalendarById('[カレンダーID]').getEvents(new Date(start), new Date(end))

で、ここで注目していただきたいのが、カレンダーIDです。みなさんがもっているGoogleアカウントにて各カレンダーがあると思いますが、それぞれにIDが振られています。 また、同じように祝日のカレンダーもGoogleカレンダーには存在します。

そのIDが ja.japanese#holiday@group.v.calendar.google.com になります。 このIDを指定して取得することで、簡単に祝日を取得することができるのです。

指定の期間の祝日を取得する

では早速、書いてみましょう。

function test() {
  var result = getEvents('2019-01-01', '2020-01-01');
  Logger.log(result)
}

function getEvents(start, end) {
  var events = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com').getEvents(new Date(start), new Date(end))
  var result = [];
  for (var i = 0; i < events.length; i++) {
    result.push({
      date: events[i].getStartTime(),
      title: events[i].getTitle()
    })
  }
  
  return result
}

これを実行してみると、以下のように、2020年の祝日の一覧を取得することができます。 f:id:ponkotsu0605:20191223234053p:plain

[19-12-23 06:40:17:122 PST] [{date=Tue Jan 01 00:00:00 GMT+09:00 2019, title=元日}, {date=Mon Jan 14 00:00:00 GMT+09:00 2019, title=成人の日}, {date=Mon Feb 11 00:00:00 GMT+09:00 2019, title=建国記念の日}, {date=Thu Mar 21 00:00:00 GMT+09:00 2019, title=春分の日}, {date=Mon Apr 29 00:00:00 GMT+09:00 2019, title=昭和の日}, {date=Tue Apr 30 00:00:00 GMT+09:00 2019, title=祝日}, {date=Wed May 01 00:00:00 GMT+09:00 2019, title=天皇の即位の日}, {date=Thu May 02 00:00:00 GMT+09:00 2019, title=祝日}, {date=Fri May 03 00:00:00 GMT+09:00 2019, title=憲法記念日}, {date=Sat May 04 00:00:00 GMT+09:00 2019, title=みどりの日}, {date=Sun May 05 00:00:00 GMT+09:00 2019, title=こどもの日}, {date=Mon May 06 00:00:00 GMT+09:00 2019, title=こどもの日 振替休日}, {date=Mon Jul 15 00:00:00 GMT+09:00 2019, title=海の日}, {date=Sun Aug 11 00:00:00 GMT+09:00 2019, title=山の日}, {date=Mon Aug 12 00:00:00 GMT+09:00 2019, title=山の日 振替休日}, {date=Mon Sep 16 00:00:00 GMT+09:00 2019, title=敬老の日}, {date=Mon Sep 23 00:00:00 GMT+09:00 2019, title=秋分の日}, {date=Mon Oct 14 00:00:00 GMT+09:00 2019, title=体育の日}, {date=Tue Oct 22 00:00:00 GMT+09:00 2019, title=即位礼正殿の儀の行われる日}, {date=Sun Nov 03 00:00:00 GMT+09:00 2019, title=文化の日}, {date=Mon Nov 04 00:00:00 GMT+09:00 2019, title=文化の日 振替休日}, {date=Sat Nov 23 00:00:00 GMT+09:00 2019, title=勤労感謝の日}, {date=Wed Jan 01 00:00:00 GMT+09:00 2020, title=元日}]

APIとして公開する

ここまでくれば後は簡単ですね!

function getEvents(start, end) {
  var events = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com').getEvents(new Date(start), new Date(end))
  var result = [];
  for (var i = 0; i < events.length; i++) {
    result.push({
      date: events[i].getStartTime(),
      title: events[i].getTitle()
    })
  }
  
  return result
}

function doGet(e) {
  var start = e.parameter.start;
  var end = e.parameter.end;
  var result = getEvents(start, end);
  
  return createResponse(result);
}

function createResponse(data) {
  var payload = JSON.stringify(data)
  var output = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);
  output.setContent(payload);
  
  return output;
}

これをAPIとして公開しましょう。 JSON形式でのAPIの公開についての詳しくは以下の記事で紹介しています。

www.pnkts.net

このAPIに対して、startとendを指定して投げてみると・・・

f:id:ponkotsu0605:20191223234426p:plain

[
    {
        "date": "2019-12-31T15:00:00.000Z",
        "title": "元日"
    },
    {
        "date": "2020-01-12T15:00:00.000Z",
        "title": "成人の日"
    },
    {
        "date": "2020-02-10T15:00:00.000Z",
        "title": "建国記念の日"
    },
    {
        "date": "2020-02-22T15:00:00.000Z",
        "title": "天皇誕生日"
    },
    {
        "date": "2020-02-23T15:00:00.000Z",
        "title": "天皇誕生日 振替休日"
    },
    {
        "date": "2020-03-19T15:00:00.000Z",
        "title": "春分の日"
    },
    {
        "date": "2020-04-28T15:00:00.000Z",
        "title": "昭和の日"
    },
    {
        "date": "2020-05-02T15:00:00.000Z",
        "title": "憲法記念日"
    },
    {
        "date": "2020-05-03T15:00:00.000Z",
        "title": "みどりの日"
    },
    {
        "date": "2020-05-04T15:00:00.000Z",
        "title": "こどもの日"
    },
    {
        "date": "2020-05-05T15:00:00.000Z",
        "title": "憲法記念日 振替休日"
    },
    {
        "date": "2020-07-22T15:00:00.000Z",
        "title": "海の日"
    },
    {
        "date": "2020-07-23T15:00:00.000Z",
        "title": "体育の日"
    },
    {
        "date": "2020-08-09T15:00:00.000Z",
        "title": "山の日"
    },
    {
        "date": "2020-09-20T15:00:00.000Z",
        "title": "敬老の日"
    },
    {
        "date": "2020-09-21T15:00:00.000Z",
        "title": "秋分の日"
    },
    {
        "date": "2020-11-02T15:00:00.000Z",
        "title": "文化の日"
    },
    {
        "date": "2020-11-22T15:00:00.000Z",
        "title": "勤労感謝の日"
    }
]

このように、startとendで指定した範囲の祝日を取得することができました。

さいごに

このように、各言語で祝日の取得というのは難しいかもしれませんが、このようにGASでAPIを公開することで、各言語でそのAPIを叩けば簡単に祝日を取得できるようになりますね!