PHPで祝日を求める

(1/1)
今回は、PHP を使って計算によって祝日を求めるプログラムを作ってみることにする。

あらかじめ断っておくが、計算によって祝日を求めることは難しい
秋分の日と敬老の日の微妙な関係」で述べたように、法律によって祝日が変わるなどのルールがあるため、ある年の祝日を計算で完全に求めることはできない。
過去の祝日であれば、実際のカレンダーから祝日を抜き出してテーブルに用意しておき、それを引いた方が確実である。また、未来の祝日についても、アプリケーションやインターネットにあるものをテーブルとして取り込み、それを引いた方が手っ取り早く確実である。

ここでは、アプリケーションやインターネットにないような未来の祝日を求めることを目的に、あえて計算で導出することを考えてみることにする。

サンプル・プログラム

祝日法を整理する

日本の祝日は、「国民の祝日に関する法律」(祝日法)という法律によって定められている。祝日法は、1948 年(昭和 23 年)に定められた。そこで今回のプログラムは、1948 年(昭和 23 年)以降の祝日について計算できるようにすることを目指す。

2009 年(平成 21 年)6 月現在の祝日を一覧にすると下記の通りである。
「開始年」は祝日が有効になった年を、「終了年」は祝日が有効な最後の年を示す。
日本の祝日一覧(2016年1月現在)
No. 月日 名称 開始年 終了年 備考
日本語 英語
固定祝日
1 1月1日 元日 New Year Day 1949 -  
2 1月15日 成人の日 Coming of Age Day 1949 1999 (※1)
3 2月11日 建国記念の日 National Foundation Day 1967 -
4 4月29日 天皇誕生日 The Emperor's Birthday 1949 1989 (※2)
5 4月29日 みどりの日 Greenery Day 1990 2006 (※2)
6 4月29日 昭和の日 Showa Day 2007 - (※2)
7 5月3日 憲法記念日 Constitution Memorial Day 1949 -
8 5月4日 国民の休日 Holiday for a Nation 1988 2006 (※3)
9 5月4日 みどりの日 Greenery Day 2007 - (※3)
10 5月5日 こどもの日 Children's Day 1949 -
11 7月20日 海の日 Marine Day 1996 -
12 8月11日 山の日 Mountain Day 2016 -
13 9月15日 敬老の日 Respect for the Aged Day 1966 2002 (※1)
14 10月10日 体育の日 Health and Sports Day 1966 1999 (※1)
15 11月3日 文化の日 National Culture Day 1948 -
16 11月23日 勤労感謝の日 Labbor Thanksgiving Day 1948 -
17 12月23日 天皇誕生日 The Emperor's Birthday 1989 -
18 4月10日 皇太子明仁親王
の結婚の儀
The Rite of Wedding of
HIH Crown Prince Akihito
1959 1959 (※4)
19 12月24日 昭和天皇
の大喪の礼
The Funeral Ceremony of Emperor Showa. 1989 1989 (※4)
20 11月12日 即位礼正殿の儀 The Ceremony of the Enthronement of
His Majesty the Emperor (at the Seiden)
1990 1990 (※4)
21 6月9日 皇太子徳仁親王
の結婚の儀
The Rite of Wedding of
HIH Crown Prince Naruhito
1993 1993 (※4)
移動祝日1
22 3月21日頃 春分の日 Vernal Equinox Day 1949 -
23 9月23日頃 秋分の日 Autumnal Equinox Day 1948 -
移動祝日2(いわゆるハッピーマンデー)
24 1月
第2月曜日
成人の日 Coming of Age Day 2000 -
25 7月
第3月曜日
海の日 Marine Day 2003 -
26 9月
第3月曜日
敬老の日 Respect for the Aged Day 2003 -
27 10月
第2月曜日
体育の日 Health and Sports Day 2000 -
振替休日(holiday in lieu)
28 祝日が日曜にあたるときは、その翌日を休日とする。1973年4月12日から適用。
【改正】祝日が日曜にあたるときは、その日後において、その日に最も近い「国民の祝日」でない日を休日。2007年1月1日から適用。
国民の休日(Citizen's Holiday)
29 その前日及び翌日が「国民の祝日」である日(日曜日にあたる日及び前項に規定する休日にあたる日を除く。)は、休日とする。1985年12月27日から適用。
【改正】その前日及び翌日が「国民の祝日」である日(「国民の祝日」でない日に限る)は、休日とする。 2005年5月20日から適用。

(※1)2000年または2002年に「移動祝日2」となる。
(※2)1990年より「みどりの日」、2007年より「昭和の日」となる。
(※3)2007年より「みどりの日」となる。
(※4)1年だけの祝日

祝日の性質に応じて、「固定祝日」「移動祝日1」「移動祝日2」「振替休日」「国民の休日」の 5 つにグルーピングしている。この名称はプログラムを作る便宜上付けたものであるので、他所では通用しない。
以下、それぞれのグループの計算方法を解説する。

サンプル・プログラムの解説:カレンダー計算

0080: /**
0081:  * 閏年かどうか判定する
0082:  * @param int $year 西暦年
0083:  * @return bool TRUE:閏年である/FALSE:平年である
0084: */
0085: function isleap($year) {
0086:     $ret = FALSE;
0087:     if ($year % 4 == 0)     $ret = TRUE;
0088:     if ($year % 100 == 0)   $ret = FALSE;
0089:     if ($year % 400 == 0)   $ret = TRUE;
0090:     return $ret;
0091: }
0092: 
0093: /**
0094:  * 指定した月の日数を返す
0095:  * @param int $year  西暦年
0096:  * @param int $month 月
0097:  * @return int 日数/FALSE:引数の異常
0098: */
0099: function getDaysInMonth($year$month) {
0100:     static $days = array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
0101:     if ($month < 1 || $month > 12)  return FALSE;
0102:     $days[2] = isleap($year) ? 29 : 28;       //閏年の判定
0103: 
0104:     return $days[$month];
0105: }
0106: 
0107: /**
0108:  * グレゴリオ暦⇒ユリウス日 変換
0109:  * @param int $year  西暦年
0110:  * @param int $month 月
0111:  * @param int $day   日
0112:  * @return double ユリウス日(JD)
0113: */
0114: function Gregorian2JD($year$month$day) {
0115:     if ($month <= 2) {
0116:         $month += 12;
0117:         $year--;
0118:     }
0119:     return floor(365.25 * $year) - floor($year / 100) + floor($year / 400) + floor(30.6001 * ($month + 1)) + $day +1720996.5;
0120: }
0121: 
0122: /**
0123:  * ユリウス日⇒グレゴリオ暦 変換
0124:  * @param double $jd ユリウス日
0125:  * @return array($year, $month, $day)  西暦年月日
0126: */
0127: function JD2Gregorian($jd) {
0128:     $jd += 0.5;
0129:     $z = floor($jd);
0130:     $f = $jd - $z;
0131:     $aa = floor(($z - 1867216.25) / 36524.25);
0132:     $a = floor($z + 1 + $aa - floor($aa / 4));
0133:     $b = $a + 1524;
0134:     $c = floor(($b - 122.1) / 365.25);
0135:     $k = floor(365.25 * $c);
0136:     $e = floor(($b - $k) / 30.6001);
0137: 
0138:     $day = floor($b - $k - floor(30.6001 * $e));
0139:     $month = ($e < 13.5) ? ($e - 1) : ($e - 13);
0140:     $year = ($month > 2.5) ? ($c - 4716) : ($c - 4715);
0141: 
0142:     return array($year$month$day);
0143: }
0144: 
0145: /**
0146:  * 曜日番号を求める
0147:  * @param int $year  西暦年
0148:  * @param int $month 月
0149:  * @param int $day   日
0150:  * @return int 曜日番号(0:日曜日, 1:月曜日...6:土曜日)
0151: */
0152: function getWeekNumber($year$month$day) {
0153:     $jd = Gregorian2JD($year$month$day);
0154:     return ($jd + 1.5) % 7;
0155: }

PHP には曜日などの計算を行うための関数として  date  が用意されている。
しかし、date はUNIX 時間を基準にしているため、1970 年(昭和 45 年)1 月 1 日以降でないと使えない。今回は 1948 年(昭和 23 年)から対応しなければならないため、別のカレンダー関数を用意する必要がある。

PHP の環境によってはカレンダー関数が利用できる。
しかし、当サーバの環境では利用できないため、同様の関数を用意することにした。

指定した月の日数を返す関数として  cal_days_in_month  があるが、これも利用できないため、代わりにユーザー関数 getDaysInMonth を用意した。ある年が閏年 (うるうどし) かどうか判定する必要があるが、これについては「PHP で閏年かどうか判定する」で解説した通りである。

紀元前 4713 年(平成 2725 年)1 月 1 日からの通日をあらわす「ユリウス日」(Julian Day)というものがある。これであれば人類の有史時代全体を網羅できるので、天文学や歴史学で重宝されている。
ユーザー関数 Gregorian2JD は、西暦年月日からユリウス日を求める。JD2Gregorian は、ユリウス日から西暦年月日を求める。
getWeekNumber は、西暦年月日に対応する曜日番号を求める。曜日番号は、日曜日が 0、月曜日が 1‥‥土曜日が 6 である。

サンプル・プログラムの解説:固定祝日

0157: /**
0158:  * 固定祝日であれば、その名称を取得する
0159:  * @param int $year  西暦年
0160:  * @param int $month 月
0161:  * @param int $day   日
0162:  * @param string lang jp=日本語名称/en=英語名称
0163:  * @return string 固定祝日の名称/FALSE=祝日ではない
0164: */
0165: function getFixedHoliday($year$month$day$lang) {
0166: //固定祝日
0167: static $fixed_holiday = array(
0168: //    月  日  開始年 終了年  名称
0169: array( 1,  1, 1949, 9999, '元日',         "New Year's Day"),
0170: array( 1, 15, 1949, 1999, '成人の日',     'Coming of Age Day'),
0171: array( 2, 11, 1967, 9999, '建国記念の日', 'National Foundation Day'),
0172: array( 4, 29, 1949, 1989, '天皇誕生日',   "The Emperor's Birthday"),
0173: array( 4, 29, 1990, 2006, 'みどりの日',   'Greenery Day'),
0174: array( 4, 29, 2007, 9999, '昭和の日',     'Showa Day'),
0175: array( 5,  3, 1949, 9999, '憲法記念日',   'Constitution Memorial Day'),
0176: array( 5,  4, 1988, 2006, '国民の休日',   'Holiday for a Nation'),
0177: array( 5,  4, 2007, 9999, 'みどりの日',   'Greenery Day'),
0178: array( 5,  5, 1949, 9999, 'こどもの日',   "Children's Day"),
0179: array( 7, 20, 1996, 2002, '海の日',       'Marine Day'),
0180: array( 8, 11, 2016, 9999, '山の日',       'Mountain Day'),
0181: array( 9, 15, 1966, 2002, '敬老の日',     'Respect for the Aged Day'),
0182: array(10, 10, 1966, 1999, '体育の日',     'Health and Sports Day'),
0183: array(11,  3, 1948, 9999, '文化の日',     'National Culture Day'),
0184: array(11, 23, 1948, 9999, '勤労感謝の日', 'Labbor Thanksgiving Day'),
0185: array(12, 23, 1989, 9999, '天皇誕生日',   "The Emperor's Birthday"),
0186: //以下、1年だけの祝日
0187: array( 4, 10, 1959, 1959, '皇太子明仁親王の結婚の儀', "The Rite of Wedding of HIH Crown Prince Akihito"),
0188: array( 2, 24, 1989, 1989, '昭和天皇の大喪の礼', "The Funeral Ceremony of Emperor Showa."),
0189: array(11, 12, 1990, 1990, '即位礼正殿の儀', "The Ceremony of the Enthronement
0190:       of His Majesty the Emperor (at the Seiden)
"),
0191: array( 6,  9, 1993, 1993, '皇太子徳仁親王の結婚の儀 ', "The Rite of Wedding of HIH Crown Prince Naruhito")
0192: );
0193: 
0194:     $name = FALSE;
0195:     foreach ($fixed_holiday as $val) {
0196:         if ($month == $val[0] && $day == $val[1]) {
0197:             if ($year >= $val[2] && $year <= $val[3]) {
0198:                 $name = preg_match("/JP/i", $lang) == 1 ? $val[4] : $val[5];
0199:                 break;
0200:             }
0201:         }
0202:     }
0203:     return $name;
0204: }

毎年月日が決まっている祝日である。
1948 年(昭和 23 年)に 9 つの祝日で始まった。ただし、7 月 20 日に公布・施行だったため、7 月 19 日以前の 6 つの祝日は翌1949 年(昭和 24 年)から有効になった。
その後、東京オリンピックの翌年(1966 年、昭和 41 年)に体育の日などが追加されていく。このときも 6 月 25 日に公布・施行だったため、建国記念の日(2 月 11 日)は翌1967 年(昭和 42 年)から有効になった。
その後、昭和天皇の崩御(1989 年、昭和 64 年)に伴い、「天皇誕生日」の名称が目まぐるしく変わる。
また、いわゆるハッピーマンデー法の成立によって、2000 年(平成 12 年)と 2003 年の二度にわたり、合計4 つの祝日が移動した。

ユーザー関数 getFixedHoliday は、西暦年月日を与え、祝日であればその名称を返す。
プログラムは、まず、固定祝日の一覧を配列 $fixed_holiday に用意する。今後、固定祝日が変更になった場合は、この配列を変更するだけで対応できるようになっている。
そして、引数の月 $month と日 $day が合致するかどうかを調べる。
祝日の名称として、日本語と英語のいずれかを返すことができるようにしてある。

サンプル・プログラムの解説:移動祝日1

0206: /**
0207:  * ある年の春分の日を求める
0208:  * @param int $year 西暦年
0209:  * @return int 日(3月の)
0210: */
0211: function getVernalEquinox($year) {
0212:     return floor(20.8431 + 0.242194 * ($year - 1980) - floor(($year - 1980) / 4));
0213: }
0214: 
0215: /**
0216:  * ある年の秋分の日を求める
0217:  * @param int $year 西暦年
0218:  * @return int 日(9月の)
0219: */
0220: function getAutumnalEquinox($year) {
0221:     return floor(23.2488 + 0.242194 * ($year - 1980) - floor(($year - 1980) / 4));
0222: }
0223: 
0224: /**
0225:  * 移動祝日(春分/秋分の日)であれば、その名称を取得する
0226:  * @param int $year  西暦年
0227:  * @param int $month 月
0228:  * @param int $day   日
0229:  * @param string lang jp=日本語名称/en=英語名称
0230:  * @return string 移動祝日の名称/FALSE=祝日ではない
0231: */
0232: function getMovableHoliday1($year$month$day$lang) {
0233:     $name = FALSE;
0234: 
0235:     //春分の日
0236:     $dd = getVernalEquinox($year);
0237:     if ($year >=1949 && $day == $dd && $month == 3) {
0238:         $name = preg_match("/JP/i", $lang) == 1 ? '春分の日' : 'Vernal Equinox Day';
0239:     }
0240:     //秋分の日
0241:     $dd = getAutumnalEquinox($year);
0242:     if ($year >=1948 && $day == $dd && $month == 9) {
0243:         $name = preg_match("/JP/i", $lang) == 1 ? '秋分の日' : 'Autumnal Equinox Day';
0244:     }
0245:     return $name;
0246: }

秋分の日と敬老の日の微妙な関係」で述べたように、「春分の日」「秋分の日」は前年度の閣議で決まる。これが一番厄介である。
秋分の日、秋分の日を天文学的な計算する手段はあるのだが、人為的に日付を変える可能性があるので、こればかりは計算で確実に求めることができない。

ユーザー関数 getVernalEquinox は天文学的に春分の日を、getAutumnalEquinox は秋分の日を計算するものである。
あくまで計算で求めているので、実際のカレンダーとは±1 日程度ズレる可能性があることに留意されたい。すでにカレンダーとして決まっている 2009 年(平成 21 年)以前の春分の日、秋分の日も計算によって求めているので、過去のカレンダーと合致しないかもしれない。

サンプル・プログラムの解説:移動祝日2

0248: /**
0249:  * ある月の第N曜日を求める
0250:  * @param int $year 西暦年
0251:  * @param int $month 月
0252:  * @param int $week  曜日番号;0 (日曜)~ 6 (土曜)
0253:  * @param int $n     第N曜日
0254:  * @return int $day 日
0255: */
0256: function getWeeksOfMonth($year$month$week$n) {
0257:     if ($n < 1)     return FALSE;
0258: 
0259:     $jd1 = Gregorian2JD($year$month, 1);
0260:     $wn1 = getWeekNumber($year$month, 1);
0261:     $dd  = $week - $wn1 < 0 ? 7 + $week - $wn1 : $week - $wn1;
0262:     $jd2 = $jd1 + $dd;
0263:     $jdn = $jd2 + 7 * ($n - 1);
0264:     list($yy$mm$dd) = JD2Gregorian($jdn);
0265: 
0266:     if ($mm != $month)   return FALSE;    //月のオーバーフロー
0267: 
0268:     return $dd;
0269: }
0270: 
0271: /**
0272:  * 移動祝日(ハッピーマンデー)であれば、その名称を取得する
0273:  * @param int $year  西暦年
0274:  * @param int $month 月
0275:  * @param int $day   日
0276:  * @param string lang jp=日本語名称/en=英語名称
0277:  * @return string 移動祝日の名称/FALSE=祝日ではない
0278: */
0279: function getMovableHoliday2($year$month$day$lang) {
0280: //移動祝日(ハッピーマンデー法)
0281: static $movable_holiday = array(
0282: //    月  曜日番号 第N曜日 開始年  終了年  名称
0283: array( 1, 1, 2, 2000, 9999, '成人の日', 'Coming of Age Day'),
0284: array( 7, 1, 3, 2003, 9999, '海の日',   'Marine Day'),
0285: array( 9, 1, 3, 2003, 9999, '敬老の日', 'Respect for the Aged Day'),
0286: array(10, 1, 2, 2000, 9999, '体育の日', 'Health and Sports Day')
0287: );
0288: 
0289:     $name = FALSE;
0290:     foreach ($movable_holiday as $val) {
0291:         if ($month == $val[0] && $day == getWeeksOfMonth($year$month$val[1]$val[2])) {
0292:             if ($year >= $val[3] && $year <= $val[4]) {
0293:                 $name = preg_match("/JP/i", $lang) == 1 ? $val[5] : $val[6];
0294:                 break;
0295:             }
0296:         }
0297:     }
0298:     return $name;
0299: }

いわゆるハッピーマンデー法で決まった祝日である。第2 月曜日または第3 月曜日が祝日に当たる。

ユーザー関数 getWeeksOfMonth は、ある月の第N 曜日を求めることができる。
将来、ハッピーフライデー法(笑)ができるかもしれないので、月曜日でなく、任意の曜日について求めることができるようにしてある。

ユーザー関数 getMovableHoliday2 は、ハッピーマンデーであれば、その名称を返す。getFixedHoliday と同様、祝日一覧を配列 $movable_holiday に用意しておく。今後、ハッピーマンデー法が変更になった場合は、この配列を変更するだけで対応できるようになっている。

サンプル・プログラムの解説:振替休日

0315: /**
0316:  * 振替休日かどうか調べる
0317:  * @param int $year  西暦年
0318:  * @param int $month 月
0319:  * @param int $day   日
0320:  * @return bool TRUE/FALSE
0321: */
0322: function isTransferHoliday($year$month$day) {
0323:     $jd = Gregorian2JD($year$month$day);
0324:     $j0 = Gregorian2JD(1973, 4, 12);
0325:     if ($jd < $j0)  return FALSE;        //有効なのは1973年4月12日以降
0326: 
0327:     //当日が祝日なら FALSE
0328:     if (isFixedMovableHoliday($year$month$day))     return FALSE;
0329: 
0330:     $n = ($year <= 2006) ? 1 : 7; //改正法なら最大7日間遡る
0331:     $jd--;                         //1日前
0332:     for ($i = 0; $i < $n$i++) {        //無限ループに陥らないように
0333:         list($yy$mm$dd) = JD2Gregorian($jd);
0334:         //祝日かつ日曜日なら振替休日
0335:         if (isFixedMovableHoliday($yy$mm$dd)
0336:             && (getWeekNumber($yy$mm$dd) == 0))     return TRUE;
0337:         //祝日でなければ打ち切り
0338:         if (! isFixedMovableHoliday($yy$mm$dd))      break;
0339:         $jd--; //1日前
0340:     }
0341:     return FALSE;
0342: }

日曜日と祝日が重なった場合、月曜日が祝日になる。これが振替休日である。1973 年(昭和 48 年)4 月 12 日からはじまった。
ところがハッピーマンデー法が制定されてから以降は、日曜日、月曜日が連続して祝日になるケースが発生する。そこで、2007 年(平成 19 年)1 月以降は、

祝日が日曜にあたるときは、その日後において、その日に最も近い「国民の祝日」でない日を休日


とすることになった。前述の場合は火曜日が祝日になる。
とくに 2009 年(平成 21 年)は、5 月 3 日の日曜日が憲法記念日、月曜日のみどりの日、火曜日のこどもの日と、祝日が 3 日連続することになった。この場合は水曜日が振替休日となる。

ユーザー関数 isTransferHoliday は、与えられた西暦年月日が振替休日かどうか調べるものである。
前日が祝日である場合は、for ループを用い、日曜日まで祝日が続いているかどうか遡ってチェックするようにしている。連続していれば、その日は振替休日である。
ここで while ではなく for ループを用いたのは、引数や他の祝日判定の異常で無限ループに陥ることがないようにするための配慮である。

サンプル・プログラムの解説:国民の休日

0344: /**
0345:  * 国民の休日かどうか調べる
0346:  * @param int $year  西暦年
0347:  * @param int $month 月
0348:  * @param int $day   日
0349:  * @return bool TRUE/FALSE
0350: */
0351: function isNationalHoliday($year$month$day) {
0352:     if ($year < 2003)   return FALSE;    //有効なのは2003年以降
0353:     $j0 = Gregorian2JD($year$month$day) - 1;  //前日
0354:     list($yy0$mm0$dd0) = JD2Gregorian($j0);
0355:     $j1 = Gregorian2JD($year$month$day) + 1;  //翌日
0356:     list($yy1$mm1$dd1) = JD2Gregorian($j1);
0357: 
0358:     //前日と翌日が固定祝日または移動祝日なら国民の休日
0359:     if (isFixedMovableHoliday($yy0$mm0$dd0)
0360:         && isFixedMovableHoliday($yy1$mm1$dd1))     return TRUE;
0361:     return FALSE;
0362: }

固定祝日、移動祝日1、移動祝日2のいずれかで挟まれた 1 日は「国民の休日」となる。2003 年(平成 15 年)以降に有効になる。

ユーザー関数 isTransferHoliday は、与えられた西暦年月日が国民の休日かどうかを調べる。
その翌日と前日が、固定祝日、移動祝日1、移動祝日2のいずれかでないかどうかを調べているだけである。

サンプル・プログラムの解説:祝日を求める

0364: /**
0365:  * 祝日であれば、その名称を取得する
0366:  * @param int $year  西暦年
0367:  * @param int $month 月
0368:  * @param int $day   日
0369:  * @param string lang jp=日本語名称/en=英語名称
0370:  * @return string 祝日の名称/FALSE=祝日ではない
0371: */
0372: function getHoliday($year$month$day$lang) {
0373:     //固定祝日
0374:     $name = getFixedHoliday($year$month$day, 'jp');
0375:     if ($name != FALSE)      return $name;
0376:     //移動祝日(春分/秋分の日)
0377:     $name = getMovableHoliday1($year$month$day, 'jp');
0378:     if ($name != FALSE)      return $name;
0379:     //移動祝日(ハッピーマンデー)
0380:     $name = getMovableHoliday2($year$month$day, 'jp');
0381:     if ($name != FALSE)      return $name;
0382:     //振替休日
0383:     if (isTransferHoliday($year$month$day)) {
0384:         return preg_match("/JP/i", $lang) == 1 ? '振替休日' : 'holiday in lieu';
0385:     }
0386:     //国民の祝日
0387:     if (isNationalHoliday($year$month$day)) {
0388:         return preg_match("/JP/i", $lang) == 1 ? '国民の休日' : "Citizen's Holiday";
0389:     }
0390:     //祝日ではない
0391:     return FALSE;
0392: }
0393: 
0394: /**
0395:  * 祝日かどうかを調べる
0396:  * @param int $year  西暦年
0397:  * @param int $month 月
0398:  * @param int $day   日
0399:  * @return bool TRUE/FALSE
0400: */
0401: function isHoliday($year$month$day) {
0402:     return getHoliday($year$month$day, 'jp') == FALSE ? FALSE : TRUE;
0403: }

ユーザー関数 getHoliday は、与えられた西暦年月日が祝日であれば、その名称を返す。
固定祝日、移動祝日1、移動祝日2、振替休日、国民の休日を順々に調べている。

ユーザー関数 isHoliday は、与えられた西暦年月日が祝日かどうかを調べるものである。

以上の関数を利用し、入力された西暦年から以降3 年分の祝日一覧を表示するのがサンプル・プログラムである。

祝日と祭日

Wikipedia によれば、「祭日」とは「宗教儀礼上重要な祭祀を行う日のこと」とされている。
戦後、GHQ の占領下において、神道に基づく儀礼は一切廃止されたため、「祭日」は無くなった。そして、国民が祝うべき「祝日」に切り替わったのである。
ところが実際は、新憲法が制定された 1947 年(昭和 22 年)を過ぎても戦前の祝日法が有効であり、ようやく 1948 年(昭和 23 年)になって新しい「国民の祝日に関する法律」(祝日法)が定められた。

『国民の祝日』の由来がわかる小事典」(所功/PHP研究所/2003 年(平成 15 年)08 月)は、祝日を
  1. 祭日に基づく祝日
  2. 国家にちなむ祝日
  3. 人生に伴う祝日
の 3 つに分類しているが、「春分の日」「秋分の日」「勤労感謝の日」は「祭日に基づく祝日」に分類している。これらは、農耕民族である日本人古来の祭礼に基づく祝日だからである。表向き、祭日が無くなったとはいえ、実はしっかりとカレンダーに根付いているのである。

参考書籍

表紙 理科年表Q&A
著者 理科年表Q&A編集委員会
出版社 丸善出版
サイズ 単行本
発売日 2003年11月
価格 1,944円(税込)
rakuten
ISBN 9784621073360
本書では、これまで理科年表編集部が受けたたくさんの質問の中から、「これはなるほど」、「これは知って便利」というテーマを選び出し、理科年表の部門「暦(こよみ)」、「天文」、「気象」、「物理/化学」、「地学」、「生物」に沿ってしぼり込み、できるだけわかりやすく解説しながら答えを書くよう努めました。
 
表紙 暦の雑学事典
著者 吉岡安之
出版社 日本実業出版社
サイズ 単行本
発売日 1999年12月
価格 1,404円(税込)
rakuten
ISBN 9784534030214
知っているとちょっと楽しい知識を満載!ミレニアムの意外な秘密がわかる。暦の歴史をたどり、ルーツを探る。いまに生きる旧暦の数々がわかる。さまざまな時計の歴史と科学を紹介。身近な暦の話題から歳時記まで暦の蘊蓄が盛りだくさん。
 
表紙 「国民の祝日」の由来がわかる小事典
著者 所功
出版社 PHP研究所
サイズ 新書
発売日 2003年08月
価格 842円(税込)
rakuten
ISBN 9784569630861
「建国記念日の日」「こどもの日」「勤労感謝の日」…。今や年間十五日にのぼる「国民の祝日」はいつ頃、どのように成立したのか。古来の民俗的な年中行事や人生儀礼に伴なう祝祭日。明治以降の国家的な祝日。さらに平成に入ってから付け加えられた「みどりの日」や「海の日」など、「国民の祝日」は古さと新しさをあわせもつ。そこには、わが国で永年育まれてきた自然と、先祖に感謝する心、共同体の人間関係を尊ぶ豊かな精神が盛り込まれている。歴史学の観点から日本人の英知を解き明かす。
 
表紙 プログラミングのセオリー
著者 矢沢久雄
出版社 技術評論社
サイズ 単行本
発売日 2008年11月
価格 2,570円(税込)
rakuten
ISBN 9784774136288
 

参考サイト

(この項おわり)
header