ツェラーの公式
ツェラーの公式(ツェラーのこうしき、英: Zeller's congruence、独: Zellers Kongruenz)とは西暦(グレゴリオ暦またはユリウス暦)の年・月・日から、その日の曜日を算出する公式である。ドイツの数学者であるクリスティアン・ツェラー (Christian Zeller) が1882年に考案した[1][2][3][4]。
呼称および表記
編集Zeller's congruence は直訳すると「Zeller の合同式」といった意味になるが、日本では主に「Zeller の公式」と呼ばれる。またカタカナ表記はドイツ語読みで「ツェラーの公式」と記すのが一般的だが[5]、英語読みで「ゼラーの公式」と表記されることもある[6][7]。
公式
編集y 年 m 月 d 日の曜日を求める。
ただし、1月と2月は、前年のそれぞれ13月・14月として扱う。たとえば、2025年1月1日・2月1日は、2024年13月1日・14月1日とする。また、紀元前 年は西暦 年として扱う(天文学的紀年法)。たとえば、紀元前1年・前2年・前3年は、0年・-1年・-2年となる。
曜日 | 日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|---|
h | 1 | 2 | 3 | 4 | 5 | 6 | 0 |
曜日 h は次の式で求められる( h は、0 から 6 でそれぞれ土曜日から金曜日を表す):
はグレゴリオ暦 (Gregorian) かユリウス暦 (Julian) かで変わる項で、
ただし
とする。
は x を超えない(x以下)の最大の整数(床関数)であり、x mod n は x を n で割った剰余である。C と Y は、(西暦が4桁の場合)西暦の上2桁と下2桁を表す中間変数で、たとえば2025年なら、それぞれ20と25になる。
適用範囲
編集1582年10月 | ||||||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
1 | 2 | 3 | 4 | 15 | 16 | |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | ||||||
以上の2つの計算式は、それぞれの暦法を過去または未来に単純に延長して使うのであれば、年数の有効範囲の限界はない(先発グレゴリオ暦、先発ユリウス暦を参照)。
しかし歴史上の実際の年月日についての曜日を知るには注意が必要である。
グレゴリウス13世は、ユリウス暦の1582年10月4日木曜日の翌日を、グレゴリオ暦の10月15日金曜日として実施した。
しかし、各国・各地方が実際にグレゴリオ暦を導入した時期は異なる場合がある。例えばイギリス帝国ではユリウス暦の1752年9月2日水曜日の翌日をグレゴリオ暦の9月14日木曜日として導入している。
1752年9月(英国) | ||||||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
1 | 2 | 14 | 15 | 16 | ||
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
そのため、知りたい年月日がユリウス暦なのかグレゴリオ暦なのかによって使用すべき式を選ぶ必要がある。
また、ガイウス・ユリウス・カエサルがユリウス暦を制定・実施したのは紀元前45年1年1月であるが、その直後の紀元前44年にカエサルが暗殺されたため、その後の閏年の設定が誤っていた時期と、それを補正した期間があった。これらの時期の閏年が何年に実施されたかについては、さまざまな主張があり議論になっている。少なくとも西暦8年以降は本来のユリウス暦のルールに則って閏年が実施されているとされている。
ゆえに西暦8年以前の日付の実際の曜日を求めるのは困難である。
ISO 8601 との関係
編集曜日 | 日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|---|
h | 1 | 2 | 3 | 4 | 5 | 6 | 0 |
D | 7 | 1 | 2 | 3 | 4 | 5 | 6 |
日付の表記の国際規格である ISO 8601が定める D(1 から 7 でそれぞれ月曜日から日曜日)を求めるには、次の式
を使う。
コンピュータでの計算
編集ツェラーの公式では年を2つの中間変数を使って計算しているがこれは筆算での計算の容易化のためで、コンピュータで計算する場合には中間変数を用いない式に変形して使用することがある[8]。
変形したグレゴリオ暦の式の例は以下の通り(1月、2月を前年の13月、14月として扱うのは同様)。
同様に変形したユリウス暦の式の例は以下の通り。
曜日 | 日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|---|
h' | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
この場合の曜日 h' は、0 から 6 でそれぞれ日曜日から土曜日を表す。
実装するうえでは、いくつか注意すべき点がある[注釈 1]。
- 負数の剰余は、開発言語などによって異なる動作をすることがある(剰余演算を参照)。上記の式は数学的定義の通り、例えば -1 mod 7 = 6 であることが前提である。
- 負数の整数除算の丸めは、開発言語などによって異なる動作をすることがある(端数処理を参照)。整数除算を使って床関数と同じ結果を得るには、負の無限大への丸めである必要がある。上記の式を整数除算でそのまま記述するには、例えば -10 / 4 が -3 である必要がある。
- 開発言語やライブラリなどによっては、例えば1月を 0 とあらわすことがあるため[9]、必要であれば変換を行う。
以下に Python3 でのグレゴリオ暦版の実装例を示す(以下の関数では月を 1 - 12 の値で受け取り、関数内に1月、2月を前年の13月、14月として扱うための処理を含む)。
def day_of_week(y, m, d):↲
y, m = (y-1, m+12) if (m < 3) else (y, m)↲
return (y + y//4 - y//100 + y//400 + (13*m + 8)//5 + d) % 7
同様の条件で、C言語での実装例を示す[注釈 2]。
int bmod(int n, int d)
{
int r = n % d;
return (r < 0) ? (r+d) : r;
}
int idiv(int n, int d)
{
int q = n / d;
return (n%d < 0) ? q-1 : q;
}
int day_of_week(int y, int m, int d)
{
if (m < 3) {
y--;
m += 12;
}
return bmod(y + idiv(y, 4) - idiv(y, 100) + idiv(y, 400) + (13*m + 8)/5 + d, 7);
}
ただし、負数の年を考慮しなくてよい場合、つまり西暦0年(紀元前1年)3月1日以降のみを対象とすればよい場合には、C言語でもPython3と同様のシンプルな実装で問題ない。
int day_of_week(int y, int m, int d)
{
if (m < 3) {
y--;
m += 12;
}
return (y + y/4 - y/100 + y/400 + (13*m + 8)/5 + d) % 7;
}
計算例
編集年月日 | 曜日 | h | h' |
---|---|---|---|
(紀元前44年3月15日) -43年3月15日 |
金曜日 | 6 | 5 |
(紀元前2年1月11日) -1年1月11日 (-2年13月11日として扱う) |
月曜日 | 2 | 1 |
1年1月1日 (0年13月1日として扱う) |
月曜日 | 2 | 1 |
1582年10月14日 (ユリウス暦1582年10月4日にあたる) |
木曜日 | 5 | 4 |
1582年10月15日 | 金曜日 | 6 | 5 |
2000年2月29日 (1999年14月29日として扱う) |
火曜日 | 3 | 2 |
2023年12月31日 | 日曜日 | 1 | 0 |
年月日 | 曜日 | h | h' |
---|---|---|---|
(紀元前44年3月15日) -43年3月15日 |
水曜日 | 4 | 3 |
(紀元前2年1月11日) -1年1月11日 (-2年13月11日として扱う) |
土曜日 | 0 | 6 |
1年1月1日 (0年13月1日として扱う) |
土曜日 | 0 | 6 |
1582年10月4日 | 木曜日 | 5 | 4 |
1582年10月5日 (グレゴリオ暦1582年10月15日にあたる) |
金曜日 | 6 | 5 |
2000年2月29日 (1999年14月29日として扱う) |
月曜日 | 2 | 1 |
2023年12月31日 | 土曜日 | 0 | 6 |
ツェラーの公式の導出
編集曜日は7日間で循環しているので、上記【※】式の 7 の剰余を求めることで曜日が判明する。即ち、
である。
曜日 | 日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|---|
h' | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
このとき h' のとり得る値は 0 から 6 で、それぞれ日曜日から土曜日を表す。
(現行のグレゴリオ暦は、1582年10月15日にこの日を金曜日であるとして施行されたが、この日を起点に遡ってグレゴリオ暦を適用すると1年1月1日は月曜日となるため h' の値が表す曜日がこのような並びになる)
【I】式が 7 の剰余である事を利用すると、以下の通り変形できる。
ここで、床関数の性質( , ただし b は整数)を利用すると、
さらに、h' が 7 の剰余であることを利用して、
と変形できる。
y = 100C + Y ( 0 ≦ Y ≦ 99, C, Y は整数)と置くと、以下の通り変形される。
h' が 7 の剰余であることを利用して、
ここで 0 ≦ Y ≦ 99より、0 ≦ Y/100 ≦ 0.99 であり、
同様に 0 ≦ Y/400 ≦ 0.2475 であり、また C/4 の小数部分は、0, 0.25, 0.5, 0.75 の何れかの値を取る為、C/4 + Y/400 の小数部分は高々 0.75 + 0.2475 = 0.9975 であり、
としてよい。よって、
曜日 | 日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|---|
h' | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
h | 1 | 2 | 3 | 4 | 5 | 6 | 0 |
このとき h' のとり得る値は 0 から 6 で、それぞれ日曜日から土曜日を表す(【I】式の場合と同様)。
演算(項)数を減らすためこの式の被除数に 1 加算すると
となり、ツェラーの公式が導出できる。
このとき h のとり得る値は 0 から 6 で、それぞれ土曜日から金曜日を表す(被除数に 1 加算しているため【I】式の場合と比べ、1日分のずれが生じた)。
日本での紹介
編集ツェラーの公式が日本で最初に紹介された時期は不明だが、以下の事例がある。
1921年(大正10年)の『日本中等教育数学会雑誌』にツェラーの公式が紹介されている[10]。
發二巻第五號ノ本欄デ中西榮作君ガ一ツノ公式ヲ紹介サレタガ The American Mathematical Monthly ノ本年6-7號ニ, プリンストン大學ノ Philip Franklin トイウ人ガ An arithmetical perpetual calender トイフ見出シデ別ノ公式ヲ載セテヰル.
ただし「ツェラーの公式を紹介している記事[11]」を紹介しており、Zellerの名前は記載されていない。そのため、ツェラーの公式を Philip Franklin が1921年に考案したと間違えられることもある[12]。
1938年(昭和13年)に『月刊数学』でZellerの名前で紹介されている[13]。
萬年暦と云ふのでちらうか.人のよく考案するものである.ずつと古いことは暦術家に尋ねなければわからないが,1887 年の Acta Math 第九巻に Christopher Zeller の作つた公式がある.
どちらの事例でもグレゴリオ暦版の公式だけが紹介されている。
脚注
編集注釈
編集出典
編集- ^ Zeller, Christian (1882) (ドイツ語), Die Grundaufgaben der Kalenderrechnung auf neue und vereinfachte Weise gelöst, V, Württembergische Vierteljahrshefte für Landesgeschichte, pp. 313-314, doi:10.53458/wvjh.v5i.14389
- ^ Zeller, Christian (1883) (ラテン語), Problema duplex Calendarii fundamentale, 11, Bulletin de la Société Mathématique de France, pp. 59-61, doi:10.24033/bsmf.254
- ^ Zeller, Christian (1885) (ドイツ語), Kalender-Formeln, 1, Mathematisch-naturwissenschaftliche Mitteilungen des mathematisch-naturwissenschaftlichen Vereins in Württemberg, pp. 54-58
- ^ Zeller, Christian (1886/1887) (ドイツ語), Kalender-Formeln, 9, Acta Mathematica, pp. 131-136, doi:10.1007/BF02406733
- ^ 細井勉; 嶋田君枝『PASCALによるプログラミング入門』産業図書、1981年、175頁。NDLJP:12631695。
- ^ 小林光夫; 荒井嘉夫『Pascal ABC : マイコンとの対話』広済堂出版、1980年5月、117頁。NDLJP:12631596。
- ^ 藤村幸三郎; 田村三郎『数学歴史パズル : 数学者も頭をひねった75問 (ブルーバックス)』講談社、1985年1月、211頁。ISBN 4-06-118192-0。NDLJP:12608305。
- ^ 奥村晴彦『C言語による標準アルゴリズム事典』(改訂新版)技術評論社、2018年5月、287頁。ISBN 978-4-7741-9690-9。
- ^ ISO/IEC 9899:1999 specification. p. 338
- ^ 鍋島「或日ノ週日ヲ知ル公式(II)」『日本中等教育数学会雑誌』第3巻第6号、1921年、211頁、doi:10.32296/jjsmet.3.6_210。
- ^ Philip Franklin (1921). “An Arithmetical Perpetual Calendar”. The American Mathematical Monthly 28 (6-7): 262. doi:10.2307/2973335.
- ^ 宮崎勝弐 著、田島一郎; 島田茂 編『数学科でのゲーム・パズル』共立出版〈教職数学シリーズ実践編〉、1985年3月、43-44頁。NDLJP:12162104。
- ^ T.M.「Perpetual Calendar」『月刊数学』第20巻、冨山房、1936年12月、6頁。
外部リンク
編集- ドイツ語版ウィキソースに本記事に関連した原文があります:"Kalender-Formeln" 1886/1887
- Mainly on Zeller's algorithms at the Wayback Machine (archived 20140111)
- RFC 3339 - 付録Bに、ツェラーの公式の変形(中間変数は使うが、日曜日は0になるように)したものが記載されている。