====== 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);
}
}