====== GoogleカレンダーからJSONPで日本の祝日一覧を取得 - GCalendar Holidays ====== コメントと更新履歴の参照は[[http://0-oo.net/log/category/google-calendar-holidays/|ゼロと無限の間のログ » GCalendar Holidays]]でどうぞ。 {{:javascript:jui-cal.png|}} [[https://developers.google.com/google-apps/calendar/|Google Calendar API V3]]から、日本の祝日データを取得して表示するJavaScriptです。\\ Googleカレンダーに登録されている祝日なので、ハッピーマンデーの時のように休日の制度が変わっても柔軟に対応できます。\\ ただしGoogleカレンダーに登録されている祝日が間違っている(あるいは最新でない)場合もそのまま表示されます。:-X [[Yahho Calendar|Yahho Calendar]]または[[http://jqueryui.com/datepicker/|jQuery UI Datepicker]]と合わせて使うと便利です。 ===== バージョン0.6.0からの変更点 ===== バージョン0.5.xまではGoogle Calendar API V2から取得していましたが、Google Calendar API V2の廃止にともない、バージョン0.6.0からはGoogle Calendar API V3から取得するようにしました。ただ、Google Calendar API V3はGoogle API KEYが必須になるため、**いったんサーバサイドのPHPでGoogle Calendar API V3からデータを取得し、そこからJavaScriptでデータを取得する**形にしました。そのPHP(GCalendar-Holidays.php)もこのページで公開しています。 これにともない取得するGoogleカレンダーは公式版の祝日カレンダーのみになりました。(GCalendar-Holidays.phpを変更すれば任意のカレンダーを取得できます。) ===== jQuery UI Datepickerに祝日を表示する ===== バージョン0.3.0からは[[http://jqueryui.com/datepicker/|jQuery UI Datepicker]]にも対応しました。\\ バージョン0.4.0からはjQuery UI Datepickerの土曜日・日曜日に背景色を付けるようにしました。 使い方は、jQuery UI Datepickerを使うページでGcalendar HolidaysのJavaScriptファイルを読み込むだけです。(下記サンプル参照) ===== サンプル ===== 下記のページで実際に使ってみてください。\\ * [[http://0-oo.net/sam/google-calendar-holidays/|GCalendar Holidaysのサンプル]] * [[http://0-oo.net/sam/google-calendar-holidays/jquery-ui-datepicker.php|jQuery UI Datepickerに祝日を表示するのサンプル]] * [[http://0-oo.net/sam/google-calendar-holidays/multi-datepickers.php|複数表示のjQuery UI Datepickerに祝日を表示するのサンプル]] ※サンプルで使っているのは最新のBeta版の場合あり ===== ライセンス ===== GCalendar Holidaysは[[http://0-oo.net/pryn/MIT_license.txt|MITライセンス]]で。\\ GCalendar HolidaysはGoogle Calendar APIを利用するので、[[http://www.google.com/googlecalendar/terms_of_use.html|Googleカレンダーの利用規約]]にも従ってください。 ===== ダウンロード ===== [[http://g.0-oo.net/gcalendar-holidays.js|gcalendar-holidays.js]] ※ダウンロードのリンク先が最新のBeta版の場合あり ===== GCalendar Holidays API リファレンス ===== ==== GCalHolidays ==== === GCalHolidays.apiUrl === * GCalendar-Holidays.phpのURLをセットしておく。 === GCalHolidays.get(callback, year, month) === * 概要 * 祝日データを取得する。 * パラメータ * callback : データ取得後に呼び出されるコールバック関数を渡す。コールバック関数には下記のような配列のデータが渡される。 [{year: 年, month: 月, date: 日, title: 祝日の名前}, {year: 年, month: 月, date: 日, title: 祝日の名前}, {year: 年, month: 月, date: 日, title: 祝日の名前}, ・ ・ ・] * year : [オプション] 対象とする年。指定しないと今年のデータを取得する。 * month : [オプション] 対象とする月。指定しないと一年分のデータを取得する。 === GCalHolidays.datepickerStyles === * [[http://jqueryui.com/datepicker/|jQuery UI Datepicker]]と合わせて使う場合の、土曜日・日曜日・祝日のstyle(CSS) ===== さらに進んだ使い方 ===== GCalendar-Holidays.phpで指定するGoogleカレンダーのIDを変更すれば、他の国の祝日や祝日以外のデータ(Googleカレンダーで公開されているイベントのデータ)も取得できます。 ===== ソースコード ===== /** * GCalendar Holidays - Googleカレンダーから日本の祝日を取得 * @see http://0-oo.net/sbox/javascript/google-calendar-holidays * @version 0.6.0 * @copyright 2008-2014 dgbadmin@gmail.com * @license http://0-oo.net/pryn/MIT_license.txt (The MIT license) */ var GCalHolidays = { /** Google Calendarから情報を取得するAPIのURL */ apiUrl: "https://gcalendar-holidays.appspot.com/", /** jQuery UI Datepicker用のstyle(Themeに合わせてお好みで上書きして使う) */ datepickerStyles: { sunday: "background-image: none; background-color: #f99", //日曜日 saturday: "background-image: none; background-color: #6cf", //土曜日 holiday: "background-image: none; background-color: #f9f" //祝日 } }; /** * 祝日を取得する * @param Function callback データ取得時に呼び出されるfunction * @param Number year (optional) 年(指定しなければ今年) * @param Number month (optional) 月(1~12 指定しなければ1年の全て) */ GCalHolidays.get = function(callback, year, month) { //日付範囲 var padZero = function(value) { return ("0" + value).slice(-2); }; var y = year || new Date().getFullYear(); var start = [y, padZero(month || 1), "01"].join("-"); var m = month || 12; var end = [y, padZero(m), padZero(new Date(y, m, 0).getDate())].join("-"); this._caches = (this._caches || {}); this._userCallback = callback; var cache = this._caches[start + ".." + end]; if (cache) { //取得済みの場合はそれを使う callback(cache, 0); return; } //URL作成 var url = GCalHolidays.apiUrl + "?timeMin=" + start + "&timeMax=" + end; //scriptタグ生成 var script = document.createElement("script"); script.type = "text/javascript"; script.src = url; script.charset = "UTF-8"; document.body.appendChild(script); }; /** * JSONPによりGoogle Calendar API経由で呼び出されるfunction * @param Object gdata カレンダーデータ * @param String start 開始日付 * @param String end 終了日付 */ GCalHolidays.decode = function(gdata, start, end) { var days = GCalHolidays._entries2days(gdata.items); //キャッシュする this._caches[start + ".." + end] = days; //コールバック this._userCallback(days, 0); // 第2引数は過去バージョンの遺産 }; /** * JSONPで取得したデータから日付情報を取り出す * @param Array entries スケジュール * @return Array 日付情報(year, month, date, title) */ GCalHolidays._entries2days = function(entries) { var days = []; var cnt = 0; if (!entries) { return days; } //シンプルな器に移す for (var i = 0, len = entries.length; i < len; i++) { var entry = entries[i]; var ymd = entry.start.date.split("T")[0].split("-"); days[cnt] = { //年月日は使いやすいように数値にする year: ymd[0] * 1, month: ymd[1] * 1, date: ymd[2] * 1, title: entry.summary }; cnt++; } return days; }; /** * jQuery UI Datepickerのカレンダーに祝日を表示する * @param Number year 表示する年 * @param Number month 表示する月 * @param Object inst Datepicker * @see http://jqueryui.com/demos/datepicker/ */ GCalHolidays.datepicker = function(year, month, inst) { setTimeout(function() { //処理後に対象のdivが再構築されるケースを回避 for (var i = 0, len = (inst.settings.numberOfMonths || 1); i < len; i++) { GCalHolidays.get(function(holidays) { for (var j = 0, len2 = holidays.length; j < len2; j++) { var h = holidays[j]; var s = "[data-year=" + h.year + "][data-month=" + (h.month - 1) + "] a" inst.dpDiv.find(s).each(function() { if ($(this).text() == h.date) { $(this).addClass("gcal-holiday").attr("title", h.title); return false; } }); } }, year, month); month++; if (month > 12) { year++; month = 1; } } }, 1); }; /** * jQuery UI Datepickerが有効な場合はイベントハンドラとstyleをセットする */ if (window.$ && $.datepicker && $.datepicker.setDefaults) { $.datepicker.setDefaults({ beforeShow: function(input, inst) { var date = $(input).datepicker("getDate") || new Date(); GCalHolidays.datepicker(date.getFullYear(), date.getMonth() + 1, inst); }, beforeShowDay: function(date) { //土日のclass属性 return [true, { 0: "gcal-sunday", 6: "gcal-saturday" }[date.getDay()] || ""]; }, onChangeMonthYear: GCalHolidays.datepicker }); $(function() { //ページ表示後に土日・祝日用のstyleをセット var styles = GCalHolidays.datepickerStyles; var css = ""; css += ".gcal-sunday .ui-state-default { " + styles.sunday + " } "; css += ".gcal-saturday .ui-state-default { " + styles.saturday + " } "; css += ".ui-widget-content .gcal-holiday { " + styles.holiday + " }"; $("head").append($('")); }); } ==== GCalendar-Holidays.php ==== $googleApiKey, 'timeMin' => $timeMin . 'T00:00:00+0900', 'timeMax' => $timeMax . 'T23:59:59+0900', 'fields' => 'items(start,summary)', ); // Google Calendar API V3のURL $apiUrl = 'https://www.googleapis.com/calendar/v3/calendars/'; $apiUrl .= rawUrlEncode($calendarId) . '/events?'; $apiUrl .= http_build_query($params); // 取得&出力 header('Content-Type: application/javascript; charset=utf-8'); echo 'GCalHolidays.decode(' . file_get_contents($apiUrl) . ', "' . $timeMin . '", "' . $timeMax . '");'; // 不正文字列は弾く function validate($date) { if (!preg_match('/^[-0-9]+\z/', $date)) { throw new Exception($date); } }