====== GoogleカレンダーからJSONPで日本の祝日一覧を取得 - GCalendar Holidays ======
コメントと更新履歴の参照は[[http://0-oo.net/log/category/google-calendar-holidays/|ゼロと無限の間のログ » GCalendar Holidays]]でどうぞ。
{{javascript:adore.png|}}
[[http://code.google.com/apis/calendar/|Google Calendar API]]から、日本の祝日データを取得して表示するJavaScriptです。\\
Googleカレンダーに登録されている祝日なので、ハッピーマンデーの時のように休日の制度が変わっても柔軟に対応できます。\\
ただしGoogleカレンダーに登録されている祝日が間違っている(あるいは最新でない)場合もそのまま表示されます。:-X
[[Yahho Calendar|Yahho Calendar]]と合わせて使うと便利です。
===== jQuery UI Datepickerに祝日を表示する =====
バージョン0.3.0からは[[http://jqueryui.com/demos/datepicker/|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に祝日を表示するのサンプル]]
※サンプルで使っているのは最新の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://0-oo.googlecode.com/svn/gcalendar-holidays.js|gcalendar-holidays.js]]
※ダウンロードのリンク先が最新のBeta版の場合あり
===== GCalendar Holidays API リファレンス =====
==== GCalHolidays ====
=== GCalHolidays.get(callback, year, month) ===
* 概要
* 祝日データを取得する。
* パラメータ
* callback : データ取得後に呼び出されるコールバック関数を渡す。コールバック関数には下記のような配列のデータが渡される。
[{year: 年, month: 月, date: 日, title: 祝日の名前},
{year: 年, month: 月, date: 日, title: 祝日の名前},
{year: 年, month: 月, date: 日, title: 祝日の名前},
・
・
・]
* year : [オプション] 対象とする年。指定しないと今年のデータを取得する。
* month : [オプション] 対象とする月。指定しないと一年分のデータを取得する。
=== GCalHolidays.userIds ===
* GoogleカレンダーのIDの配列を指定するプロパティ
* デフォルトはGoogleの公式の日本の祝日
=== GCalHolidays.maxResults ===
* 取得するデータの最大件数を指定するプロパティ
* デフォルトは31
===== さらに進んだ使い方 =====
GCalHolidaysのプロパティを変更すれば、他の国の祝日や祝日以外のデータ(Googleカレンダーで公開されているイベントのデータ)も取得できます。
例:サッカーの日本代表のスケジュールを取得する場合
GCalHolidays.userIds = ["k1b51v9t41vn3k0agk648pr7p0@group.calendar.google.com"];
GCalHolidays.max = 50;
GCalHolidays.get(callback, 2008);
===== ソースコード =====
/**
* GCalendar Holidays - Googleカレンダーから日本の祝日を取得
* @see http://0-oo.net/sbox/javascript/google-calendar-holidays
* @version 0.3.0
* @copyright 2008-2010 dgbadmin@gmail.com
* @license http://0-oo.net/pryn/MIT_license.txt (The MIT license)
*
* See also
* @see http://code.google.com/intl/ja/apis/calendar/data/2.0/reference.html
* @see http://code.google.com/intl/ja/apis/gdata/docs/json.html
*/
var GCalHolidays = {
/** GoogleカレンダーのID(複数でも可) */
userIds: [
"japanese__ja@holiday.calendar.google.com" //Google公式版
//"japanese@holiday.calendar.google.com" //Google公式(英語)版
//"outid3el0qkcrsuf89fltf7a4qbacgt9@import.calendar.google.com" //mozilla.org版
],
/** 取得するイベント(スケジュール)の最大件数 */
maxResults: 31,
// @see http://code.google.com/intl/ja/apis/calendar/data/2.0/reference.html#Visibility
visibility: "public",
// @see http://code.google.com/intl/ja/apis/calendar/data/2.0/reference.html#Projection
projection: "full-noattendees"
};
/**
* 祝日を取得する
* @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;
for (var i = 0, len = this.userIds.length; i < len; i++) {
//取得済みの場合はそれを使う
var cache = this._caches[i + ":" + start + ".." + end];
if (cache) {
callback(cache, i);
continue;
}
//URL作成
var url = location.protocol + "//www.google.com/calendar/feeds/";
url += encodeURIComponent(this.userIds[i]) + "/";
url += this.visibility + "/" + this.projection;
url += "?alt=json-in-script&callback=GCalHolidays.decode";
url += "&max-results=" + this.maxResults;
url += "&start-min=" + start + "&start-max=" + 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 カレンダーデータ
*/
GCalHolidays.decode = function(gdata) {
var days = GCalHolidays._entries2days(gdata.feed.entry);
var links = gdata.feed.link;
var href;
for (var j = 0, len2 = links.length; j < len2; j++) {
if (links[j].rel == "self") {
href = links[j].href;
}
}
//どのカレンダーか特定する
var userId = decodeURIComponent(href.split("/")[5]);
var index;
for (var i = 0, len = this.userIds.length; i < len; i++) {
if (this.userIds[i] == userId) {
index = i;
break;
}
}
//キャッシュする
var range = href.match(/\d{4}-\d{2}-\d{2}/g); //日付範囲の最初の日と最後の日
this._caches[index + ":" + range[0] + ".." + range[1]] = days;
//コールバック
this._userCallback(days, index);
};
/**
* JSONPで取得したデータから日付情報を取り出す
* @param Array entries スケジュール
* @return Array 日付情報(year, month, date, title)
*/
GCalHolidays._entries2days = function(entries) {
if (!entries) {
return [];
}
//日付順にソート
entries.sort(function(a, b) {
return (a.gd$when[0].startTime > b.gd$when[0].startTime) ? 1 : -1;
});
//シンプルな器に移す
var days = [];
for (var i = 0, len = entries.length; i < len; i++) {
var ymd = entries[i].gd$when[0].startTime.split("T")[0].split("-");
var title = entries[i].title.$t;
//年月日は使いやすいように数値にする
days[i] = { year: ymd[0] * 1, month: ymd[1] * 1, date: ymd[2] * 1, title: title };
}
return days;
};
/**
* jQuery UI Datepickerのカレンダーに祝日を表示する
* @see http://jqueryui.com/demos/datepicker/
*/
GCalHolidays.datepicker = function(year, month, inst) {
//祝日のstyle
var holidayStyle = { backgroundImage: "none", backgroundColor: "#fcf" };
setTimeout(function() { //処理後に対象のdivが再構築されるケースを回避
GCalHolidays.get(function(holidays) {
for (var i = 0, len = holidays.length; i < len; i++) {
var holiday = holidays[i];
if (holiday.year != year || holiday.month != month) {
return; //既に別の月を表示している場合は何もしない
}
inst.dpDiv.find("a").each(function() {
if ($(this).text() == holiday.date) {
$(this).attr("title", holiday.title).css(holidayStyle);
return false;
}
});
}
}, year, month);
}, 1);
};
/**
* jQuery UI Datepickerが有効な場合、イベントハンドラを登録する
*/
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);
},
onChangeMonthYear: GCalHolidays.datepicker
});
}