こんにちは!エンジニアの仁木です。
最近は雨が続いていたこともあり、少し暑さが和らいできましたね。
眠る時にもエアコンをつけなくても眠れるようになってきました。
さて、本日は日本の祝日一覧をGoogleカレンダーを使って、PHPで取得するための方法をご紹介したいと思います。
カレンダーのようなスケジュール機能のあるアプリケーションで、祝日の表示は必要になる場面は多くなると思います。そんな時にどうやって祝日を取得するのか、その方法を見ていきましょう。
いきなり余談となりますが、そもそも祝日って、誰がどのようにして決めているのでしょうか?
祝日は「国民の祝日に関する法律」に基づいて決められています。ちゃんと法律が制定されているんですね。
例えば、「成人の日は1月の第2月曜」であったり、「憲法記念日は5月3日」というように法律で定められています。
また、法律に明記されてはいませんが、祝日が日曜になった場合、振替休日として一番近い平日を休日になります。
ちなみに内閣府のHPには今年の祝日の一覧が掲載されています。
上記のように、祝日は毎年決まった日にちで固定されているわけではなく、年ごとに変わるのでプログラムで真っ向から対応するのはおそらく大変でしょう。もっと簡単に別のリソースから手に入るのであればそうしたいです。
実は先程の内閣府のページには祝日の一覧を記載したCSVファイルも用意されています。
このCSVファイルをプログラムで取得して祝日一覧を取得する方法もあるようですが、今回はこの方法ではなく、Google Calendarから取得する方法にします。
Google Calendarには、日本の祝日をイベントとして登録しているアカウントがあり、そのアカウントのイベント情報をAPIで取得することで、祝日一覧が取得できるようになっているんですね。
では実際にAPIを使えるようにしていきましょう。
GoogleのAPI全般の利用にはGoogleアカウントが必須です。
Googleアカウントを持っていない方は先にアカウントを作成してください。
Googleアカウントにログインした状態で「Google Cloud Platform」のページにアクセスして新規プロジェクトを作成します。既存のプロジェクトで新たにGoogle Calendar APIを利用する場合は、作成済みのプロジェクトを選択してください。
※APIはリクエスト数に応じて課金が発生するので、プロジェクトの作成時に請求先アカウントの紐付けが必要になります。請求先アカウントの作り方については本記事では割愛させていただきます。
ナビゲーションメニューの「APIとサービス」から「ライブラリ」の画面を開き、検索フォームに「Google Calendar API」と入力・検索して有効化します。
プログラム上でAPIにリクエストを送信するためには「認証情報」を設定し、APIキーを取得しなければいけません。
認証情報では、APIをリクエストできるサーバーやドメインを制限し、特定の環境でのみリクエストを認証するよう設定します。
APIの制限を行わないと、万が一APIキーが不正に使用されてしまった場合、リクエスト回数に応じて課金が発生してしまったりとトラブルの原因となるので、しっかりと制限はしておきましょう。
認証情報画面の上部にある「認証情報を作成」から新たに認証情報を作成します。
今回APIはサーバー上でPHPでリクエストを送るので、「キーの制限」はIPアドレスで制限します。
PHPのプログラムが実行されるWebサーバーのIPアドレスを追加します。
テスト環境や開発環境でも利用する場合はそれぞれのIPアドレスも追加しておきます。
また、使用できるAPIも制限できます。今回だと使用するのはGoogle Calendar APIのみになるので、このAPIのみ指定することで意図しないAPIの呼び出しを防ぐことができます。
最後に保存を行うとAPIキーが発行されます。
今後の実装でAPIにリクエストを送信する際に、このAPIキーが必要になります。
APIの準備ができれば実装になります。
今回はcurlを使ってリクエストを送信して、祝日一覧のデータをJSONで取得します。
まずは完成したソースコードをいきなり載せちゃいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// 祝日の取得範囲を決める // start_monthからの月の祝日を取得する(今年の1月1日を指定) $start_month = mktime(0,0,0,1,1,(int)$date->format('Y')); // end_monthまでの月の祝日を取得する(今年の12月31日を指定) $end_month = mktime(0,0,0,1,0,(int)$date->format('Y') + 1); // APIリクエスト先のURL $url = sprintf( "https://www.googleapis.com/calendar/v3/calendars/%s/events?key=%s&timeMin=%s&timeMax=%s&orderBy=startTime&singleEvents=true", 'japanese__ja@holiday.calendar.google.com', GOOGLE_API_KEY, date('Y-m-d', $start_month).'T00:00:00Z', date('Y-m-d', $end_month).'T00:00:00Z' ); // curlの設定 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // リクエスト処理の実行 $responce = curl_exec($ch); curl_close($ch); // 取得結果をJSONから配列に変換 $result = json_decode($responce, true); // 祝日一覧を取得 $holidays = $result['items']; |
上から順番に説明していきます。
はじめに、今年の1月1日から12月31日までの範囲の祝日を取得するために、取得する開始日と終了日を指定しています。
mktime関数では指定した日時のタイムスタンプを取得できます。
引数は順番に「時」「分」「秒」「月」「日」「年」となります。
$start_monthは1月1日とわかりやすいですが、$end_monthの引数を見ると「日」のパラメーターが0になっていますね。これはmktime関数が、「日」の引数に0を指定すると前月の末日を返すため、このようになっています。
「年」の引数が、(int)$date->format(‘Y’) + 1になっているので、「翌年の1月1日の前日 = 今年の年末」となるわけですね。
ここではAPIにリクエストするURLを作成しています。
‘japanese__ja@holiday.calendar.google.com’は日本の祝日が登録されているアカウントです。
GOOGLE_API_KEYは先程取得したGoogle Calendar APIのAPIキーを指定します。
date(‘Y-m-d’, $start_month).’T00:00:00Z’と date(‘Y-m-d’, $end_month).’T00:00:00Z’は1~4行目で用意した取得開始日と終了日をタイムスタンプから、APIで指定できる日付のフォーマットに変換しています。
ここから最後までの部分では、curlを使ってAPIにリクエストして、API受け取ったレスポンスから休日一覧のデータを取得しています。
APIからのレスポンスはJSON形式で返されるので、json_decode関数で配列に変換します。
さらに祝日一覧は配列の中の”items“のキーの中に格納されているので、そこから取り出してプログラムで使うことができます。
上記でAPIから日本の祝日一覧が取得できましたね!
しかし、祝日というのは常日頃から変更されるものではありません。
なのに、プログラムが実行されるたびにAPIにリクエストするのは無駄とも言えるでしょう。GoogleのAPIは使用回数に応じて課金も発生するので、できればリクエスト回数は抑えたいものです。
なので、一度取得した祝日一覧はテキストファイルやデータベースなど、サーバー側でデータを保持するようにしておくと最初の1回目以降はAPIにリクエストしなくても祝日一覧のデータを取得できます。
1 2 3 4 |
file_put_contents( "holidaylist/holiday-".date('Y').".json", json_encode($holidayEvents) ); |
上記のコードの例では年単位で取得した祝日のデータを「hoiday-YYYY.json」ファイルにJSON形式のテキストとして保存しています。
もし今年の祝日一覧のデータが必要になれば次回以降はこのファイルを参照すれば良いですね。
かなり短いソースコードで簡単に祝日一覧を取得できましたね。
どちらかというと、APIの使うまでの設定回りの方がややこしいのではないのでしょうか。
エンジニアの人たちはソースコードを書く以外にも、今回使用したGoogle Cloud PlarformやAWS、はたまたGithubなど、SaaSのWebアプリケーションも多く使いこなせる必要性が高くなってきたなと感じます。