イースターを計算するプログラム

イースターを計算するプログラムを題材にしてみました。 イースターとは日本人にはあまり馴染みがないかもしれませんが、イースターの日の決め方に計算方法が詳しく出ています。 ここではこのページの手順をスクリプトにコメントとして組み込み、これにしたがって組んでみることにします。

#! /usr/bin/gawk -f
# easter_date.awk
#   http://code.nanigac.com/source/view/728
#   http://www.geocities.co.jp/HeartLand/1987/easterdate.html

BEGIN {
    year = ARGV[1] ? ARGV[1] : 2009;
    print easter_date(year);
}

# easter_date():    西暦を入力するとイースターの日付を返す
#   in:     西暦 year
#   out:    year " 年のイースターは " month " 月 " day " 日です。" の形式
function easter_date(year) {
    # 試してみたい方は、次のようなアルゴリズムによって1900年から2099年までの
    # イースターの日が計算できます
    #   メトン周期: http://ja.wikipedia.org/wiki/章
    if (year < 1900 || year > 2099) {
        return "メトン周期で計算できません。";
    }

    # まず調べたい年の西暦年を19で割った余りを計算します
    rem = year % 19;
    # その余りに11をかけて225から引いた数字をDとします
    D = 225 - rem * 11;
    # もしDが51以上の時は51未満になるまで30で引き、改めてそれをDとします
    if (D >= 51) {
        while (D >= 51) {
            D = D - 30;
        }
    }
    # もし、Dが48よりも大きい時はそれから1を引きます
    if (D > 48) {
        D = D - 1;
    }
    # 西暦年と、西暦年を4で割った数字(小数点以下切り捨て)と、D+1とを足し、
    # それを7で割った余りをEとします
    E = (year + int(year / 4) + (D + 1)) % 7;
    # Dに7を足してEで引き、それをQとします
    Q = D + 7 - E;
    # もし、Qが31以下の時はイースターは3月でその数字がイースター日付を
    # 表わします。
    # Qが32以上の場合はイースターは4月でQから31を引いた数字が日付を表わします
    if (Q <= 31) {
        month = 3;
        day   = Q;
    } else {
        month = 4;
        day   = Q - 31;
    }

    return year " 年のイースターは " month " 月 " day " 日です。";
}

ここでは計算の元になっているメトン周期 (Metonic Cycle) が 1900 年から 2099 年までと説明のページに書かれているので、入力チェックも行っています。

実際に実行してみましょう。

$ nawk -f easter_date.awk
2009 年のイースターは 4 月 12 日です。
$ nawk -f easter_date.awk 2006
2006 年のイースターは 4 月 16 日です。
$ nawk -f easter_date.awk 2100
メトン周期で計算できません。

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png