ツェラーの公式

提供: testwiki
ナビゲーションに移動 検索に移動

テンプレート:出典の明記 ツェラーの公式(ツェラーのこうしき、テンプレート:Lang-en-shortテンプレート:Lang-de-short)とは西暦グレゴリオ暦またはユリウス暦)のから、その日の曜日を算出する公式である。ドイツ数学者であるクリスティアン・ツェラー (テンプレート:Interlang) が1882年に考案した[1][2][3][4]

特定の日からの通算日数(ユリウス通日Rata Dieなど)を求め、その剰余から曜日を求める計算と本質は同じである。

呼称および表記

Zeller's congruence は直訳すると「Zeller の合同式」といった意味になるが、日本では主に「Zeller の公式」と呼ばれる。またカタカナ表記はドイツ語読みで「ツェラーの公式」と記すのが一般的だが[5]、英語読みで「ゼラーの公式」と表記されることもある[6][7]

公式

テンプレート:Mvarテンプレート:Mvarテンプレート:Mvar 日の曜日を求める。

ただし、1月2月は、前年のそれぞれ13月・14月として扱う。たとえば、2025年1月1日・2月1日は、2024年13月1日・14月1日とする。また、紀元前 y^ 年は西暦 1y^ 年として扱う(天文学的紀年法)。たとえば、紀元前1年・前2年・前3年は、0年・-1年・-2年となる。

曜日
h 1 2 3 4 5 6 0

曜日 テンプレート:Mvar は次の式で求められる( テンプレート:Mvar は、0 から 6 でそれぞれ土曜日から金曜日を表す):

h=(d+26(m+1)10+Y+Y4+Γ)mod7

Γグレゴリオ暦 (テンプレート:En) かユリウス暦 (テンプレート:En) かで変わる項で、

Γ={2C+C4: Gregorian (1582y)C+5: Julian (4y1582)

ただし

C=y100
Y=ymod100

とする。

xテンプレート:Mvar を超えない(テンプレート:Mvar以下)の最大の整数(床関数)であり、テンプレート:Mathテンプレート:Mvarテンプレート:Mvar で割った剰余である。テンプレート:Mvarテンプレート:Mvar は、(西暦が4桁の場合)西暦の上2桁と下2桁を表す中間変数で、たとえば2025年なら、それぞれ20と25になる。

適用範囲

テンプレート:1582年10月のカレンダー

以上の2つの計算式は、それぞれの暦法を過去または未来に単純に延長して使うのであれば、年数の有効範囲の限界はない(先発グレゴリオ暦先発ユリウス暦を参照)。

しかし歴史上の実際の年月日についての曜日を知るには注意が必要である。

グレゴリウス13世は、ユリウス暦1582年10月4日木曜日の翌日を、グレゴリオ暦の10月15日金曜日として実施した。

テンプレート:Clear

しかし、各国・各地方が実際にグレゴリオ暦を導入した時期は異なる場合がある。例えばイギリス帝国ではユリウス暦1752年9月2日水曜日の翌日をグレゴリオ暦の9月14日木曜日として導入している。 テンプレート:1752年9月のカレンダー (英国) テンプレート:Clear

そのため、知りたい年月日がユリウス暦なのかグレゴリオ暦なのかによって使用すべき式を選ぶ必要がある。 テンプレート:Main

また、ガイウス・ユリウス・カエサルユリウス暦を制定・実施したのは紀元前45年1年1月であるが、その直後の紀元前44年にカエサルが暗殺されたため、その後の閏年の設定が誤っていた時期と、それを補正した期間があった。これらの時期の閏年が何年に実施されたかについては、さまざまな主張があり議論になっている。少なくとも西暦8年以降は本来のユリウス暦のルールに則って閏年が実施されているとされている。 テンプレート:Main

ゆえに西暦8年以前の日付の実際の曜日を求めるのは困難である。

ISO 8601 との関係

曜日
h 1 2 3 4 5 6 0
D 7 1 2 3 4 5 6

日付の表記の国際規格である ISO 8601が定める テンプレート:Mvar(1 から 7 でそれぞれ月曜日から日曜日)を求めるには、次の式

D=((d+26(m+1)10+Y+Y4+Γ+5)mod7)+1

を使う。

コンピュータでの計算

ツェラーの公式では年を2つの中間変数を使って計算しているがこれは筆算での計算の容易化のためで、コンピュータで計算する場合には中間変数を用いない式に変形して使用することがある[8]

変形したグレゴリオ暦の式の例は以下の通り(1月、2月を前年の13月、14月として扱うのは同様)。

h=(y+y4y100+y400+13m+85+d)mod7

同様に変形したユリウス暦の式の例は以下の通り。

h=(y+y4+13m+85+d+5)mod7
曜日
h' 0 1 2 3 4 5 6

この場合の曜日 テンプレート:Mvar は、0 から 6 でそれぞれ日曜日から土曜日を表す。

実装するうえでは、いくつか注意すべき点があるテンプレート:Efn

  • 負数の剰余は、開発言語などによって異なる動作をすることがある(剰余演算を参照)。上記の式は数学的定義の通り、例えば テンプレート:Math であることが前提である。
  • 負数の整数除算の丸めは、開発言語などによって異なる動作をすることがある(端数処理を参照)。整数除算を使って床関数と同じ結果を得るには、負の無限大への丸めである必要がある。上記の式を整数除算でそのまま記述するには、例えば テンプレート:Mathテンプレート:Math である必要がある。
  • 開発言語やライブラリなどによっては、例えば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言語での実装例を示すテンプレート:Efn

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;
}

計算例

グレゴリオ暦テンプレート:Efnでの曜日の計算例を示す。

グレゴリオ暦の計算例
年月日 曜日 テンプレート:Mvar テンプレート:Mvar
(紀元前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

ユリウス暦テンプレート:Efnでの曜日の計算例を示す。

ユリウス暦の計算例
年月日 曜日 テンプレート:Mvar テンプレート:Mvar
(紀元前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日間で循環しているので、上記テンプレート:EquationNote式の 7 の剰余を求めることで曜日が判明する。即ち、

テンプレート:NumBlk

である。

曜日
h' 0 1 2 3 4 5 6

このとき テンプレート:Mvar のとり得る値は 0 から 6 で、それぞれ日曜日から土曜日を表す。

(現行のグレゴリオ暦は、1582年10月15日にこの日を金曜日であるとして施行されたが、この日を起点に遡ってグレゴリオ暦を適用すると1年1月1日は月曜日となるため テンプレート:Mvar の値が表す曜日がこのような並びになる)

テンプレート:EquationNote式が 7 の剰余である事を利用すると、以下の通り変形できる。

h=(7(52y62)+y+y4y100+y400+153(m+1)5+6+d)mod7=(y+y4y100+y400+153(m+1)5+6+d)mod7

ここで、床関数の性質( a+b=a+b , ただし テンプレート:Mvar は整数)を利用すると、

h=(y+y4y100+y400+153(m+1)5+6+d)mod7=(y+y4y100+y400+153m+153+305+d)mod7=(y+y4y100+y400+153m+1835+d)mod7=(y+y4y100+y400+35(4m+5)+13m+85+d)mod7=(y+y4y100+y400+7(4m+5)+13m+85+d)mod7

さらに、テンプレート:Mvar が 7 の剰余であることを利用して、

h=(y+y4y100+y400+13m+85+d)mod7

と変形できる。

テンプレート:Math ( テンプレート:Math, テンプレート:Mvar, テンプレート:Mvar は整数)と置くと、以下の通り変形される。

h=(100C+Y+100C+Y4100C+Y100+100C+Y400+13m+85+d)mod7=(100C+Y+25C+Y4C+Y100+C4+Y400+26m+26101+d)mod7=(100C+Y+25C+Y4C+Y100+C4+Y400+26m+26101+d)mod7=(100C+Y+25C+Y4CY100+C4+Y400+26m+2610+d1)mod7=(124C+Y+Y4Y100+C4+Y400+26m+2610+d1)mod7=((7×18)C2C+Y+Y4Y100+C4+Y400+26m+2610+d1)mod7

テンプレート:Mvar が 7 の剰余であることを利用して、

h=(2C+Y+Y4Y100+C4+Y400+26m+2610+d1)mod7

ここで テンプレート:Mathより、テンプレート:Math であり、

Y100=0

同様に テンプレート:Math であり、また テンプレート:Math の小数部分は、0, 0.25, 0.5, 0.75 の何れかの値を取る為、テンプレート:Math の小数部分は高々 テンプレート:Math であり、

C4+Y400=C4

としてよい。よって、

h=(2C+Y+Y4+C4+26m+2610+d1)mod7
曜日
h' 0 1 2 3 4 5 6
h 1 2 3 4 5 6 0

このとき テンプレート:Mvar のとり得る値は 0 から 6 で、それぞれ日曜日から土曜日を表す(テンプレート:EquationNote式の場合と同様)。

演算(項)数を減らすためこの式の被除数に 1 加算すると

h=(2C+Y+Y4+C4+26(m+1)10+d)mod7

となり、ツェラーの公式が導出できる。

このとき テンプレート:Mvar のとり得る値は 0 から 6 で、それぞれ土曜日から金曜日を表す(被除数に 1 加算しているためテンプレート:EquationNote式の場合と比べ、1日分のずれが生じた)。

日本での紹介

ツェラーの公式が日本で最初に紹介された時期は不明だが、以下の事例がある。

1921年(大正10年)の『日本中等教育数学会雑誌』にツェラーの公式が紹介されている[10]

テンプレート:Quote

ただし「ツェラーの公式を紹介している記事[11]」を紹介しており、Zellerの名前は記載されていない。そのため、ツェラーの公式を Philip Franklin が1921年に考案したと間違えられることもある[12]

1938年(昭和13年)に『月刊数学』でZellerの名前で紹介されている[13]

テンプレート:Quote

どちらの事例でもグレゴリオ暦版の公式だけが紹介されている。

脚注

テンプレート:脚注ヘルプ

注釈

テンプレート:Notelist

出典

テンプレート:Reflist

外部リンク