祝日を求めるjavascript
//祝日を求めるjavascript 昔書いたやつ | |
// Ported From Calendar::Japanese::Holiday.pm | |
"use strict" | |
var FurikaeStr = '振替休日'; | |
var staticHolidays = [ | |
// 4/29 みどりの日 : 昭和の日 変更 | |
// みどりの日は5/4に移行 | |
{ | |
'start' : 2007, | |
'end' : 2999, | |
'days' : { | |
1 : { 1 : '元日'}, | |
2 : {11 : '建国記念の日'}, | |
4 : {29 : '昭和の日'}, | |
5 : { | |
3 : '憲法記念日', | |
4 : 'みどりの日', | |
5 : 'こどもの日' | |
}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
}, | |
12 : {23 : '天皇誕生日'} | |
} | |
}, | |
// 海の日,敬老の日がHappy Mondayに | |
{ | |
'start' : 2003, | |
'end' : 2006, | |
'days' : { | |
1 : { 1 : '元日'}, | |
2 : {11 : '建国記念の日'}, | |
4 : {29 : 'みどりの日'}, | |
5 : { | |
3 : '憲法記念日', | |
5 : 'こどもの日' | |
}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
}, | |
12 : {23 : '天皇誕生日'} | |
} | |
}, | |
// 成人の日,体育の日がHappy Mondayに | |
{ | |
'start' : 2000, | |
'end' : 2002, | |
'days' : { | |
1 : { 1 : '元日'}, | |
2 : {11 : '建国記念の日'}, | |
4 : {29 : 'みどりの日'}, | |
5 : { | |
3 : '憲法記念日', | |
5 : 'こどもの日' | |
}, | |
7 : {20 : '海の日'}, | |
9 : {15 : '敬老の日'}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
}, | |
12 : {23 : '天皇誕生日'} | |
} | |
}, | |
// 海の日追加 | |
{ | |
'start' : 1996, | |
'end' : 1999, | |
'days' : { | |
1 : { | |
1 : '元日', | |
15 : '成人の日' | |
}, | |
2 : {11 : '建国記念の日'}, | |
4 : {29 : 'みどりの日'}, | |
5 : { | |
3 : '憲法記念日', | |
5 : 'こどもの日' | |
}, | |
7 : {20 : '海の日'}, | |
9 : {15 : '敬老の日'}, | |
10 : {10 : '体育の日'}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
}, | |
12 : {23 : '天皇誕生日'} | |
} | |
}, | |
// 天皇誕生日変更 4/29 : 12/23 | |
// 旧天皇誕生日をみどりの日に変更 | |
{ | |
'start' : 1989, | |
'end' : 1995, | |
'days' : { | |
1 : { | |
1 : '元日', | |
15 : '成人の日' | |
}, | |
2 : {11 : '建国記念の日'}, | |
4 : {29 : 'みどりの日'}, | |
5 : { | |
3 : '憲法記念日', | |
5 : 'こどもの日' | |
}, | |
9 : {15 : '敬老の日'}, | |
10 : {10 : '体育の日'}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
}, | |
12 : {23 : '天皇誕生日'} | |
} | |
}, | |
// 建国記念の日追加 | |
{ | |
'start' : 1967, | |
'end' : 1988, | |
'days' : { | |
1 : { | |
1 : '元日', | |
15 : '成人の日' | |
}, | |
2 : {11 : '建国記念の日'}, | |
4 : {29 : '天皇誕生日'}, | |
5 : { | |
3 : '憲法記念日', | |
5 : 'こどもの日' | |
}, | |
9 : {15 : '敬老の日'}, | |
10 : {10 : '体育の日'}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
} | |
} | |
}, | |
// 敬老の日,体育の日追加 | |
{ | |
'start' : 1966, | |
'end' : 1966, | |
'days' : { | |
1 : { | |
1 : '元日', | |
15 : '成人の日' | |
}, | |
4 : {29 : '天皇誕生日'}, | |
5 : { | |
3 : '憲法記念日', | |
5 : 'こどもの日' | |
}, | |
9 : {15 : '敬老の日'}, | |
10 : {10 : '体育の日'}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
} | |
} | |
}, | |
// 国民の祝日に関する法律に定められた祝日のうち7/20以前のものを追加 | |
{ | |
'start' : 1949, | |
'end' : 1965, | |
'days' : { | |
1 : { | |
1 : '元日', | |
15 : '成人の日' | |
}, | |
4 : {29 : '天皇誕生日'}, | |
5 : { | |
3 : '憲法記念日', | |
5 : 'こどもの日' | |
}, | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
} | |
} | |
}, | |
// 国民の祝日に関する法律 1948/7/20制定 | |
{ | |
'start' : 1948, | |
'end' : 1948, | |
'days' : { | |
11 : { | |
3 : '文化の日', | |
23 : '勤労感謝の日' | |
} | |
} | |
} | |
]; | |
var ExceptionalHolidays = { | |
195904 : {10 : '皇太子明仁親王の結婚の儀'}, | |
198902 : {24 : '昭和天皇の大喪の礼'}, | |
199011 : {12 : '即位礼正殿の儀'}, | |
199306 : { 9 : '皇太子徳仁親王の結婚の儀'} | |
}; | |
var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; | |
function days_in_month(year, month) { | |
var days = daysInMonth[month - 1]; | |
if (month == 2 && year % 4 == 0) { | |
if (year % 100 == 0) { | |
if (year % 400 == 0) {return days + 1;} | |
return days; | |
} | |
return days + 1; | |
} | |
return days; | |
} | |
// 指定曜日の日付一覧を配列で返す | |
function weekdays(year, mon, wday) { | |
var week_days = []; | |
var wd = (new Date(year, mon-1, 1)).getDay(); | |
// 指定曜日の最初の日付(カレンダー的に空欄の場合は0以下の値となる) | |
var start = 1 - wd + wday; | |
var last_day = days_in_month(year, mon); | |
for (var day = start ; day <= last_day ; day += 7) { | |
if (day > 0) { | |
week_days.push(day); | |
} | |
} | |
return week_days; | |
} | |
function lookup_holiday_table(year) {//参照が返るので注意 | |
for (var i = 0; i < staticHolidays.length; i++) { | |
if (staticHolidays[i].start <= year && year <= staticHolidays[i].end) { | |
return staticHolidays[i].days; | |
} | |
} | |
return false; | |
} | |
// 春分の日 | |
// Ref to. | |
// http://www.nao.ac.jp/QA/faq/a0301.html | |
// http://ja.wikipedia.org/wiki/%E6%98%A5%E5%88%86%E3%81%AE%E6%97%A5 | |
function shunbun_day(year) { | |
var day; | |
var mod = year % 4; | |
if (mod == 0) { | |
if (1900 <= year && year <= 1956) {day = 21;} | |
else if (1960 <= year && year <= 2088) {day = 20;} | |
else if (2092 <= year && year <= 2096) {day = 19;} | |
} else if (mod == 1) { | |
if (1901 <= year && year <= 1989) {day = 21;} | |
else if (1993 <= year && year <= 2097) {day = 20;} | |
} else if (mod == 2) { | |
if (1902 <= year && year <= 2022) {day = 21;} | |
else if (2026 <= year && year <= 2098) {day = 20;} | |
} else if (mod == 3) { | |
if (1903 <= year && year <= 1923) {day = 22;} | |
else if (1927 <= year && year <= 2055) {day = 21;} | |
else if (2059 <= year && year <= 2099) {day = 20;} | |
} | |
return day; | |
} | |
// 秋分の日 | |
function shuubun_day(year) { | |
var day; | |
var mod = year % 4; | |
if (mod == 0) { | |
if (year == 1900) {day = 23;} | |
else if (1904 <= year && year <= 2008) {day = 23;} | |
else if (2012 <= year && year <= 2096) {day = 22;} | |
} else if (mod == 1) { | |
if (1901 <= year && year <= 1917) {day = 24;} | |
else if (1921 <= year && year <= 2041) {day = 23;} | |
else if (2045 <= year && year <= 2097) {day = 22;} | |
} else if (mod == 2) { | |
if (1902 <= year && year <= 1946) {day = 24;} | |
else if (1950 <= year && year <= 2074) {day = 23;} | |
else if (2078 <= year && year <= 2098) {day = 22;} | |
} else if (mod == 3) { | |
if (1903 <= year && year <= 1979) {day = 24;} | |
else if (1983 <= year && year <= 2099) {day = 23;} | |
} | |
return day; | |
} | |
function get_furikae_days(year, mon, holidays_tbl){ | |
var days = {}; | |
if (year < 1973) { return days; } | |
for (var h_day in holidays_tbl) { | |
h_day = parseInt(h_day); | |
var name = holidays_tbl[h_day]; | |
// 祝日が日曜日かチェック | |
var wday = (new Date(year, mon-1, h_day)).getDay(); | |
if (wday == 0) { | |
var furikae_day = h_day + 1; | |
if (year >= 2007) { | |
// 振り替えた先も祝日ならさらに進める | |
while(holidays_tbl[furikae_day]){furikae_day++;} | |
days[furikae_day] = name; | |
} | |
else if(!holidays_tbl[furikae_day]){ | |
days[furikae_day] = name; | |
} | |
} | |
} | |
return days; | |
} | |
function getHolidays(year, mon, furikae) { | |
var holiday_tbl = lookup_holiday_table(year); | |
//祝日を見に行く 該当が無ければ抜ける。 | |
if (!holiday_tbl){ return false; } | |
var holidays = _clone(holiday_tbl[mon]); | |
// Happy Monday (成人の日、海の日、敬老の日、体育の日) | |
var mondays = weekdays(year, mon, 1); // 月曜日の一覧 | |
if (year >= 2000) { | |
if (mon == 1) {holidays[mondays[1]] = '成人の日';} | |
if (mon == 10){holidays[mondays[1]] = '体育の日';} | |
} | |
if (year >= 2003) { | |
if (mon == 7) {holidays[mondays[2]] = '海の日';} | |
if (mon == 9) {holidays[mondays[2]] = '敬老の日';} | |
} | |
// 不定なもの | |
if (mon == 3) {holidays[shunbun_day(year)] = '春分の日';} | |
if (mon == 9) {holidays[shuubun_day(year)] = '秋分の日';} | |
// 例外的なもの | |
var yymm = year; | |
if (mon < 10){ | |
yymm += "" + "0"; | |
} | |
yymm += "" + mon; | |
if (ExceptionalHolidays[yymm]) { | |
for (var day in ExceptionalHolidays[yymm]){ | |
holidays[day] = ExceptionalHolidays[yymm][day]; | |
} | |
} | |
// 国民の休日 | |
if (year >= 1986) { | |
// 祝日に挟まれた平日を探す (祝日A - 平日B - 祝日C) | |
for(var day in holidays) { | |
day = parseInt(day); | |
if ( holidays[day + 2] && !holidays[day + 1]) { | |
var wday = (new Date(year, mon-1, day)).getDay(); | |
// Aが日曜の時は平日Bはただの振り替え休日 | |
// Bが日曜の場合も国民の休日とはならない | |
if(wday == 0 || wday == 6){ | |
continue; | |
} | |
holidays[day + 1] = '国民の休日'; | |
} | |
} | |
} | |
// 振り替え休日も含める | |
if (furikae) { | |
var furikae_days = get_furikae_days(year, mon, holidays); | |
for (var val in furikae_days) { | |
holidays[val] = FurikaeStr; | |
} | |
} | |
return holidays; | |
} | |
var Cache_holidays_Year = 0; | |
var Cache_holidays_Month = 0; | |
var Cache_holidays; | |
function isHoliday(year, mon, day, furikae){ | |
var holidays; | |
if (year == Cache_holidays_Year && mon == Cache_holidays_Month){ | |
holidays = Cache_holidays; // From Cache | |
} else { | |
holidays = getHolidays(year, mon, 1); | |
if (!holidays) { | |
return false; | |
} | |
// Cache | |
Cache_holidays = holidays; | |
Cache_holidays_Year = year; | |
Cache_holidays_Month = mon; | |
} | |
if (!holidays[day]){ return false; } | |
if (!furikae && holidays[day] == FurikaeStr){ return false; } | |
return holidays[day]; | |
} | |
function _clone(obj){//shallow copy | |
var result = {}; | |
for(var i in obj){ | |
result[i] = obj[i]; | |
} | |
return result; | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
var hols = getHolidays(2009,5,true); | |
for(var i in hols){ | |
document.write(i + ": " +hols[i] + "<br>"); | |
} | |
document.write(isHoliday(2009,5,3,true)); |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
</head> | |
<body> | |
<script src="japanese.holiday.js" charset="UTF-8"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
有用なスクリプトを公開下さりありがとうございます。
試したところ、
359 行目 contunue -> continue
308 行目 holiday_tbl -> holidays_tbl
にタイプミスがありました。
また、
https://ja.wikipedia.org/wiki/%E5%9B%BD%E6%B0%91%E3%81%AE%E7%A5%9D%E6%97%A5 によれば、
によれば、
1948/03/21 は 祝日法制定前
1973/02/12 は 振替休日制定前
で、それぞれ休日ではないようです。
335行目、294行目に、これらを除くためのチェックを加えられそうです。