まあ、それを見るだけで正しいことがわかります...配列が正しいと仮定すると、t[]
たった12回のスポットチェックで確認できます(任意の日/年を使用して毎月1回)。
これy -= m < 3
はいいトリックです。3 月 1 日に開始し、2 月 28 日 (または 29 日) に終了する「仮想年」を作成し、余分な日 (ある場合) を年末に置きます。というか、昨年末。たとえば、仮想年 2011 は 3 月 1 日に始まり、2 月 29 日に終了しますが、仮想年 2012 は 3 月 1 日に始まり、翌 2 月 28 日に終了します。
仮想年の終わりに閏年の追加日を置くことで、残りの式は大幅に簡素化されます。
合計を見てみましょう:
(y + y/4 - y/100 + y/400 + t[m-1] + d) % 7
通常、1 年は 365 日です。つまり、52 週プラス 1 日です。そのため、一般的に、曜日は 1 年に 1 日ずれます。それがこのy
用語が貢献しているものです。年ごとに 1 日が加算されます。
しかし、4 年に一度は閏年です。これらは、4 年ごとに 1 日余分に貢献します。仮想年を使用するおかげでy/4
、合計に追加するだけで、うるう日の数を数えることができy
ます。(この式は、整数除算が切り捨てられることを前提としていることに注意してください。)
しかし、100 年ごとは閏年ではないため、これは正しくありません。したがって、 off を減算する必要がありますy/100
。
ただし、400 年ごとに再びうるう年になります。したがって、追加する必要がありy/400
ます。
最後に、日付と、月d
に依存するテーブルからのオフセットを追加するだけです (1 年内の月の境界はかなり恣意的であるため)。
次に、1 週間の長さは mod 7 です。
(たとえば、週が 8 日の場合、この数式で何が変わるでしょうか? 明らかに mod 8 になります。また、365 % 8 == 5 であるため、y
も である必要があります。また、月の表も調整する必要があります。それでおしまい。)5*y
t[]
ちなみに、カレンダーが「9999年まで有効」というウィキペディアの記述は、完全に恣意的なものです。この式は、10 年、100 年、1000 年、100 万年など、グレゴリオ暦に固執する期間に適しています。
[編集]
上記の議論は本質的に帰納法による証明です。つまり、式が特定の (y,m,d) に対して有効であると仮定すると、(y+1,m,d) および (y,m,d+1) に対して有効であることを証明できます。(ここで、y は 3 月 1 日から始まる「仮想年」です。) 重要な問題は、ある年から次の年に移動するときに合計が正しい量だけ変化するかどうかです。うるう年のルールを知っていて、「仮想年」が年末に余分な日を持っていれば、それは自明です。