曜日の計算
ツェラー(Zeller)の公式を使って曜日を求めます。
制約)西暦4年から後の西暦を求めます。
y年M月D日の曜日を求める。
C = y div 100 : つまり上位2桁
Y = y mod 100 : つまり下位2桁
例)2023年:C = 20, Y = 23
ただし、1月、2月の場合は、前年の13月14月として計算します。
例)2020年2月の場合、2019年14月として計算します。
曜日Hは、 0:土曜日、1:日曜日、2:月曜日、3:火曜日
4:水曜日、5:木曜日、6:金曜日
計算式)
H = ( D + ^( ( 26 * ( M + 1 ) ) / 10 )^ + Y + ^( Y / 4 )^ + G ) mod 7
ここで、^( 実数 )^は、実数を超えない最大の整数です。ガウス記号を便宜上^ ^ で表現しました。
prologでは、floor/1で求まります。
ここで、定数Gは、1582年を堺に計算方法が変わります。
1582年の境は、前後どちらに含むか曖昧です。地域差
各国一気に変えたわけではないからです。=<1582か?<1582か?前者で計算します。
IF ( y < 4 ) THEN 計算しない。
IF ( y =< 1582 ) THEN G = ( -C + 5 )
IF ( 1582 < y ) THEN G = ( -2 * C ) + ^( C / 4 )^
♪ プログラムコード code
cat youbi.pl % youbi.pl youbi( Year, _, _, _ ):- Year < 4, !, fail. youbi( Year, Month, D, Youbi ):- c_y_m( Year, Month, C, Y, M ), g( Year, C, G ), H is ( D + floor( ( 26 * ( M + 1 ) ) / 10 ) + Y + floor( Y / 4 ) + G ) mod 7, henkan(H, Youbi ). c_y_m( Year, Month, C, Y, M ):- ( Month =< 2 ) -> ( CY is Year - 1, C is CY div 100, Y is CY mod 100, M is Month + 12 ) ; ( CY is Year, C is CY div 100, Y is CY mod 100, M is Month ). g( Year, C, G ):- ( Year =< 1582 ) -> ( G is ( -1 ) * C + 5 ) ; ( G is ( -2 ) * C + floor( C / 4 ) ). henkan( 0, '土' ). henkan( 1, '日' ). henkan( 2, '月' ). henkan( 3, '火' ). henkan( 4, '水' ). henkan( 5, '木' ). henkan( 6, '金' ).
実行例
$ swipl -sq youbi.pl ?- youbi( 2023, 1, 1, Youbi ). Youbi = 日. ?- youbi( 1965, 6, 9, Watakusi ). Watakusi = 水. ?- youbi( 1953, 1, 5, Tuma ). Tuma = 月. ?- Toshi_no_sa is 1965 - 1953. Toshi_no_sa = 12. ?-