YUIのJavaScriptカレンダーを日本語化&ポップアップ対応&祝日も表示 - Yahho Calendar [ゼロと無限の間に]というサイトでGoogleカレンダーの祝日情報を取得して、カレンダーポップアップを表示するサンプルが公開されていたのですが、何故かGoogleカレンダーの祝日情報は元旦の振替休日(2012年)しか登録されていないので、振替休日をJavaScript内で算出するように修正してみました。
振替休日と国民の休日の算出方法でお悩みの方がいましたら、続きをご覧ください。
- 振替休日の算出 Wikipediaの説明によると
「国民の祝日」が日曜日に当たるときは、その日後においてその日に最も近い「国民の祝日」でない日を休日とする
と決まっています。
なので、(1) 祝日が日曜日だったら、祝日を1日ずらす
を(1)、(2)に該当しない日にちになるまで繰り返すというような処理で算出できるようになります。
(2) ずらした祝日が他の祝日と重なった場合、祝日を1日ずらす
それを関数にしたのがこちらになります。/** * 振替休日を算出する * @param Date ymdDate 休日 * @param entries 休日リスト * @param next 指定した休日の次の休日の引数 */ GCalHolidays._compensating_holiday = function(ymdDate, entries, next) { var nextYmd = null; var _ymdDate = new Date(); _ymdDate.setTime(ymdDate.getTime()); // if (entries.length > next) { nextYmd = new Date(entries[next].gd$when[0].startTime.split("T")[0].replace("-", "/")); } // 日曜日の場合は、振替休日にする if (_ymdDate.getDay() == 0) { _ymdDate.setTime(_ymdDate.getTime() + (1000 * 60 * 60 * 24)); // 再帰して、振替休日にした日が休日の場合、再度休日を算出する _ymdDate = GCalHolidays._compensating_holiday(_ymdDate, entries, next); } // 振替休日が祝日だった場合 else if (nextYmd != null && _ymdDate.getTime() == nextYmd.getTime()) { // 何故かたまにちゃんと振替休日が登録されている。 if (entries[next].title.$t == "振替休日") { return null; } else { _ymdDate.setTime(ymdDate.getTime() + (1000 * 60 * 60 * 24)); // 再帰して、振替休日にした日が休日の場合、再度休日を算出する _ymdDate = GCalHolidays._compensating_holiday(_ymdDate, entries, (next + 1)); } } return _ymdDate; };
- 国民の休日の算出 前後を祝日にはさまれた休日でない日は休日が適用され「国民の休日」となります。
過去には2009年の9月に適用されました。
これは、単純に連続する2つの休日の間隔が2日の場合、間の一日を休日にすればよいことになります。
これをコードにすると下記のようになります。// 国民の休日(tmpDate = 前の祝日 ymdDate = 後の祝日) if (tmpDate != null && (ymdDate.getTime() - tmpDate.getTime()) == (2 * 1000 * 60 * 60 * 24)) { counter += 1; var holidayDate = new Date(); holidayDate.setTime(tmpDate.getTime() + (1000 * 60 * 60 * 24)); }
/** * 振替休日を算出する * @param Date ymdDate 休日 * @param entries 休日リスト * @param next 指定した休日の次の休日の引数 */ GCalHolidays._compensating_holiday = function(ymdDate, entries, next) { var nextYmd = null; var _ymdDate = new Date(); _ymdDate.setTime(ymdDate.getTime()); // if (entries.length > next) { nextYmd = new Date(entries[next].gd$when[0].startTime.split("T")[0].replace("-", "/")); } // 日曜日の場合は、振替休日にする if (_ymdDate.getDay() == 0) { _ymdDate.setTime(_ymdDate.getTime() + (1000 * 60 * 60 * 24)); // 再帰して、振替休日にした日が休日の場合、再度休日を算出する _ymdDate = GCalHolidays._compensating_holiday(_ymdDate, entries, next); } // 振替休日が祝日だった場合 else if (nextYmd != null && _ymdDate.getTime() == nextYmd.getTime()) { // 何故かたまにちゃんと振替休日が登録されている。 if (entries[next].title.$t == "振替休日") { return null; } else { _ymdDate.setTime(ymdDate.getTime() + (1000 * 60 * 60 * 24)); // 再帰して、振替休日にした日が休日の場合、再度休日を算出する _ymdDate = GCalHolidays._compensating_holiday(_ymdDate, entries, (next + 1)); } } return _ymdDate; }; /** * JSONPで取得したデータから日付情報を取り出す * @param Array entries スケジュール * @return Array 日付情報(year, month, date, title) */ GCalHolidays._entries2days = function(entries) { var days = []; var counter = 0; var tmpDate = null; var nextIsShuubun = false; var addExtraDays = function () { // 振替休日の算出 ymdDate = GCalHolidays._compensating_holiday(baseDate, entries, (i + 1)); ymdDate = (ymdDate == null) ? baseDate : ymdDate; // 振替休日を追加する if(ymdDate.getTime() != baseDate.getTime()) { counter += 1; days[(i + counter)] = {year: ymdDate.getFullYear(), month: ymdDate.getMonth() + 1, date: ymdDate.getDate(), title: "振替休日"}; } // 国民の休日 if (tmpDate != null && (ymdDate.getTime() - tmpDate.getTime()) == (2 * 1000 * 60 * 60 * 24)) { counter += 1; var holidayDate = new Date(); holidayDate.setTime(tmpDate.getTime() + (1000 * 60 * 60 * 24)); days[(i + counter)] = {year: holidayDate.getFullYear(), month: holidayDate.getMonth() + 1, date: holidayDate.getDate(), title: "国民の休日"}; } } var addShuubun = function() { //年月日は使いやすいように数値にする days[(i + counter)] = {year:baseDate.getFullYear(), month:9, date:23, title:"秋分の日"}; var _baseDate = new Date(); _baseDate.setTime(baseDate.getTime()); baseDate.setMonth(8); baseDate.setDate(23); // 振替休日の算出 ymdDate = GCalHolidays._compensating_holiday(baseDate, entries, (i + 1)); ymdDate = (ymdDate == null) ? baseDate : ymdDate; // 振替休日、国民の休日などを追加する addExtraDays(); baseDate.setTime(_baseDate.getTime()); counter += 1; } if (!entries) { return days; } //日付順にソート entries.sort(function(a, b) { return (a.gd$when[0].startTime > b.gd$when[0].startTime) ? 1 : -1; }); //日付順にソート var ymdDate = null; //シンプルな器に移す for (var i = 0, len = entries.length; i < len; i++) { var title = entries[i].title.$t; // 何故か2009年に秋分の日が抜けているので対応。 if (nextIsShuubun && title != "秋分の日") { alert(title); addShuubun(); } var baseDate = new Date(entries[i].gd$when[0].startTime.split("T")[0].replace("-", "/")); //年月日は使いやすいように数値にする days[(i + counter)] = { year: baseDate.getFullYear(), month: baseDate.getMonth() + 1, date: baseDate.getDate(), title: title }; // 振替休日、国民の休日などを追加する addExtraDays(); tmpDate = ymdDate; nextIsShuubun = (title == "敬老の日"); } if (nextIsShuubun == true) { addShuubun(); } //日付順にソート days.sort(function(a, b) { return (new Date(a.year + "/" + a.month + "/" + a.date).getTime() > new Date(b.year + "/" + b.month + "/" + b.date).getTime()) ? 1 : -1; }); return days; };
0 件のコメント:
コメントを投稿