2011年7月24日日曜日

曜日の計算

あなたの誕生日は何曜日でしょう?など、曜日を教えるなんてネタがありますが、意味の理解しやすい曜日の計算方法がネットでもなかなか見当たらないので、私なりに考えてみました。
(ネットで調べられる計算方法や公式は、計算量を減らしたりするために工夫がしてあるので、私には素直に理解がしにくいので、工夫はおいおいしてみるかな。)

まず規則の確認から。

<規則>
曜日は、7日周期。
1年は原則365日(平年(へいねん))だけど、
以下に該当する年は366日(閏年(うるうどし))。
4で割り切れる年は閏年。
ただし、100で割り切れる年は平年。
ただし、400で割り切れる年は閏年。

<計算方針>
求めたい年月日が、曜日の解っている日(基準日)から何日経過しているか計算し、その値を曜日周期の7で割った余りが0なら基準日と同じ曜日、余りが1なら基準日の次の曜日、、、となる。

西暦元年元旦から計算できるよう、解りやすくするため、基準日を西暦1年1月0日(紀元前1年12月31日)とする。

<計算方法>
求めたい年月日を、Y年M月D日とする。
(たとえば2011年6月15日とすると)

求めたい年月日が基準日から何日経過しているかをEとする。
Eは、以下の和である。

SY = 基準日から求めたい年の前年の末日までの日数
(1年1月0日から2010年12月31日までの日数)
SM = 求めたい年の前月の末日までの日数
(1月0日から5月31日までの日数)
D =  求めたい月の求めたい日までの日数
(6月0日から6月15日までの日数)

E = SY + SM + D

SYを計算する。
ここでSYは閏年があるので、ちょっと厄介であるが、考えてみると、
4年に1度の閏年は平年より1日増え、
100年に1度の平年は閏年より1日減ったとも言えるし、
400年に1度の閏年は平年より1日増え、閏年より1日減り、結局は閏年なので1日増える。
数式にした方が分かりやすいか。。

SY = 365 * (Y-1) + floor{(Y-1)/4} - floor{(Y-1)/100} + floor{(Y-1)/400}

※floor(x)とはxを越えない最大の整数という意味。つまり小数点以下を切捨て。

SMを計算する。
SMは月によって日数が異なるし、閏年か平年かで2月の日数も異なるので、月の条件判定が必要だが、ひとまず強引に数式にすると、

SM = sum{n=1→M-1, g(n)}

※g(x)とはx月の日数を表す関数とする。
※sum{n=1→m,f(n)}とは、nが1からmまでのf(n)の和。

ひとまず、月の日数g(x)の定義を確認すると。
1,3,5,7,8,10,12月は31日。
4,6,9,11月は30日。
2月は平年が28日、閏年が29日。

ある月までの日数の和は、以下。
1月までは31日。
2月までは59日。(閏年は60日)
3月までは90日。(91日)
4月までは120日。(左の数値に+1。以下同様)
5月までは151日。
6月までは181日。
7月までは212日。
8月までは243日。
9月までは273日。
10月までは304日。
11月までは334日。

結局、まとめると、
Y年M月D日の曜日Eを求める数式は、以下となる。

E = mod[365 * (Y-1) + floor{(Y-1)/4} - floor{(Y-1)/100} + floor{(Y-1)/400}
      +  sum{n=1→M-1, g(n)} + D , 7]

※mod(x,y)とは、xをyで割った余り。

Eが0なら基準日と同じ曜日、1なら基準日の次の曜日、、、、となる。

<補足>
では、基準日(西暦1年1月0日)は何曜日か計算すると、この閏年の規則であるグレゴリオ暦が始まったのが、1582年10月15日(金)なので、このときEは、

E = mod(577736,7) = 5

つまり、基準日は金曜日の5日前の日曜日。
おお、西暦元年元旦(1年1月1日)は月曜日から始まっててキリがいいな。

確認のため、西暦2011年6月15日を計算すると、

E = mod(734303,7) = 3

つまり基準日の日曜日から3日後の水曜日。
カレンダーで確認しても確かに水曜日。

<注意事項>
補足でも記述しましたが、この閏年の規則(グレゴリオ暦)が適用されたのは、1582年10月15日(金)からなので、基準日を含めてこれ以前で、上記で計算できる曜日は計算の都合上の曜日です。
ただ、コンピュータで計算している曜日計算は、式は違えど、グレゴリオ暦前提が多いようです。

さらに、もっと前から曜日を正確に把握できるよう、wikipediaで調べると、
グレゴリオ暦の以前はユリウス暦という規則で、閏年は単純に4年に一度だったり、さらに紀元8年から閏年が開始(紀元4年は平年)しているし、その前は、3年に一度の閏年だったり、例外的に閏年を止めた年があったり、当然さらに前は閏年がなかったり、月の日数が異なり、超複雑です。もっと言うと、グレゴリオ暦を採用した年月日が国によっても違うので、もうわけが分からなくなります。

まあ、人類誕生や地球誕生は何曜日でしょう?とかビッグバンは何曜日でしょう?など天文学的になると曜日なんて意味ないから、いいか。

0 件のコメント: