JavaScript
カレンダー

1948年以降の祝日等を計算するJavaScriptコード

(本記事は旧boiledorange73の記事です。元記事投稿は2014年12月です)


はじめに

JavaScriptで1948年以降の祝日をしっかり計算するプログラムを作ってみました。

「A列車で行こう3DS」は、シナリオが高度経済成長から現代までさまざまあって、年代ごとに若干ずつ異なる祝日計算をしっかり行っていて、これに感化されたためです。

あと、とりあえずポストして画像アップロード上限を増やそうという魂胆もあります。


祝日等について


「祝日」「振替休日」「国民の休日」「年末年始」

用語の統一のため、だらっと書きます。

ここで言う「祝日」は、「国民の祝日に関する法律」(以下「祝日法」)第二条を根拠とするものを指します。本法は1948年施行ですが、何度か改定されていて、日付が変更になったものや新設されたものがあります。また、ここでいう「振替休日」は祝日法第三条2項に言う休日を指し、「国民の休日」は祝日法第三条3項に言う休日を指します。

また、「年末年始」は「 行政機関の休日に関する法律」第一条1項三号を根拠とするものを指します。

「祝日等」は「祝日」「振替休日」「国民の休日」「年末年始」の全てを指します。


祝日等計算する場合の計算順序

祝日等の計算順序は次の通りとします (2018年12月11日版)。


  • 指定月と、前月、翌月の祝日(振替休日、国民の祝日等を考慮しない)を計算します。


    • 翌月を計算しないと、2019年4月を指定した時に、4月29日と5月1日との間に設定される国民の祝日を計算できないからです。

    • 前月、翌月を月初から月末まで計算する必要はありませんが、今後必要かも知れませんし、なんとなくやってます。

    • 前月は不要ですが、今後必要かも知れませんし、なんとなくやってます。



  • 指定年が1973年以降の場合、祝日が日曜日にかかっていたら直近の平日(祝日でも日曜でもない日)を振替休日にします


    • 現時点では祝日から直近の平日までの間に日曜日をはさむことはありませんので無駄があります



  • 指定年が1986年以降の場合、祝日Aの2日後が祝日で、祝日Aの1日後が祝日でも振替休日でも日曜日でもない場合、祝日Aの1日後を国民の休日にします


    • 現在は振替休日や日曜で国民の休日が消えることはありませんが、かつて5月4日が祝日でなかった頃は実際に消えました(1986年, 1987年, 1992年, 1997年, 1998年, 2003年)



  • 1月1,2,3日、12月29,30,31日のうち、祝日等でも日曜日でもない日を年末年始にします(オプション)


祝日計算の要素


計算方法からみた祝日の分類

計算方法の違いから分類すると、元日(1月1日)などの固定日、成人の日(1月第2月曜日)などの移動日、春分の日、秋分の日、の4種に分けられます。

固定日は非常に簡単ですが、移動日、春分の日、秋分の日は若干考えないといけません。


移動日に関する計算


MJD

MJD(修正ユリウス日)は日数計算等、シリアルな日が欲しい場合や、曜日計算等、年や月の周期と異なる周期を対象にした計算を行う際には必須です。

算出方法についてはWikiPediaのユリウス通日を参照して下さい。

グレゴリオ暦の年、月コード、日から修正ユリウス日を求める関数を次に示します。

hdayjp.calcMJD = function(y, m, d) {

if( m <= 1 ) {
y--;
m += 12;
}
return Math.floor(365.25*y)
+ Math.floor(y/400)
- Math.floor(y/100)
+ Math.floor(30.59*(m-1))
+ d - 678912;
}

ただし、本コードでは月コードを0始まりとしているので、月についてズレが生じます。


ある月の月初の曜日

グレゴリオ暦の年月日をMJDに変換してしまえば、シリアルな日数になるので、7の余剰で計算できます。

ただし、MJD初日が日曜というわけでもないでしょうから、何らかの固定値を足す必要があります。

次のように3を足すと、月初の曜日(0はじまり)が出ます。

(MJD(y,m,1) + 3) % 7


ある月の第n週のw曜日にあたる日を得る

ある月の第1週のw曜日(wは0はじまり)にあたる日を得て、n週(nは1はじまり)なら(n-1)*7日進めればOK。

w=月初の曜日なら1日が第1週のw曜日にあたる日、w=月初の曜日+1なら2日、となっています。ということは、w-月初の曜日+1だろうと考えられます。

しかし、曜日コードは[0,6]なので、w-月初の曜日+1は[-5,7]となります。第1週のw曜日にあたる日は1日から7日の間でなければなりません。よって、7を足して、かつ余剰を取るようにする必要があります。

これをまとめると、次のようになります。

(n-1)*7 + (7+w-月初の曜日(y,m)) % 7 + 1


春分、秋分の簡易計算式

春分の日、秋分の日の日付は、祝日法によると、それぞれ、春分日、秋分日となります。

ある年の春分日および秋分日は、その前の年の2月の最初の平日に発行される官報に「暦要項」が掲載されることとなっていて、その掲載をもって正式決定となります。国立天文台による解説を参照して下さい。

http://oshiete.goo.ne.jp/qa/1454974.html に簡易計算式が出ていましたので、流用しました。ただし、本当にそうなるかは分かりません。


1980年以前

上述の簡易計算式は1980年以後で有効です。

http://www.asahi-net.or.jp/~ci5m-nmr/misc/equinox.html を参照すると、1979年で上述の簡易計算が適用できないことが分かります。

このページを参考にして、1948年から1979年の春分日、秋分日は次のような計算式となります。


  • 春分日は、西暦年が1960以上で4で割り切れる年は3月20日、それ以外は21日。

  • 秋分日は、西暦年を4で割ったあまりが3の年は9月24日、それ以外は23日。


1948年7月以降のみ有効

祝日法は1948年7月20日制定、即日施行となっています。つまり、1948年でも秋分の日から有効で、元日からこどもの日までは1949年になってはじめて現れます。

この点は注意しないと、ありもしない祝日が出現することになります。


その他


常設祝日の一時的移動

2020年は、海の日が7月第3月曜日から7月23日に、スポーツの日が10月第2月曜日から7月24日に、山の日が8月11日から8月10日に、それぞれ移動します。

irregularHDaysクラスを用意して、年ごとに、特定の祝日について月日指定のみです(とりあえず2020年だけの話なのでこれで十分)が移動できるようにしました。

2018年6月13日に更新しました。


月をまたぐ国民の休日

月をまたがない大前提だったのですが、2019年5月1日が祝日になるのですが、問題は4月30日。これまで対象月の祝日だけから国民の休日を計算していましたが、2019年4月30日は2019年5月1日が祝日になっているのが分からないと計算できません。よって、対象月の前月と後月との祝日を計算するようにしました。

2018年11月14日に更新しました。


臨時休日の追加

天皇の即位の日および即位の礼正殿の儀の日付が決定したことを受け、追加しました。

2018年12月11日に更新しました。


ソースコード

https://github.com/boiledorange73/hdayjp.js に置いてみました。

hday.calculate(y, m)(祝日、振替休日、国民の休日を算出したい場合) または hday.calculate(y, m, true)(祝日、振替休日、国民の休日のほか、年末年始も算出したい場合)とします。

ここでyはグレゴリオ暦年、mは0はじまりの月コード(0は1月, 1は2月, ... 11は12月)としています。

0はじまりと1はじまりが混じっていますが、英語表記で、数字を使うものは1はじまり、数字を使わないもの(JanuaryとかSundayとか)は0はじまり、としています。


本記事のライセンス

クリエイティブ・コモンズ・ライセンス

この記事は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。