1 ヶ月カレンダー

awk で作られたカレンダーのプログラムを探していたのですが、見つからなかったので、自分で作ってみました。 cal コマンドのような指定ができますが、1 ヶ月分しか表示しません。 また、gawk の mktime() 関数や strftime() 関数を多用しているため、gawk, xgawk のみの動作となっています、

#! /usr/local/bin/gawk -f
# cal.awk
# カレンダーを表示する
# usage: gawk -f cal.awk [[month] year]

BEGIN {
    # オプションの設定
    year  = (ARGV[1] && ARGV[2]) ? ARGV[2] : ARGV[1] ? ARGV[1] : strftime("%Y");
    month = (ARGV[1] && ARGV[2]) ? ARGV[1] : strftime("%m");

    month = sprintf("%02d", month);

    month_days = "31 28 31 30 31 30 31 31 30 31 30 31 ";

    split(month_days, arr_days);

    # うるう年の計算
    leap = (year % 400 == 0) ? 1 : (year % 100 == 0) ? 0 : (year % 4 == 0) ? 1 : 0;

    # うるう年の場合に 2 月を 29 日にする
    if (leap == 1) {
        arr_days[2] = 29;
    }


    # タイトル部分の印字
    print "    " year " / " month;
    print "SU MO TU WE TH FR SA";

    # その月の最初 1 日が何曜日かによってスペースを加える
    for (i = 0; i < strftime("%w", mktime(year " " month " 1 12 00 00")); i++) {
        space = space "   ";
    }

    printf("%s", space);
    # その月の日数だけループ
    for (i = 1; i <= arr_days[month + 0]; i++) {
        # 日曜日の場合に改行する
        if (strftime("%w", mktime(year " " month " " i " 12 00 00")) == 0 &&
            i != 1) {
            print "";
        }
        printf("%2d ", i);
    }
    print "";
}

故意に条件演算子 (三項演算子) を使っているため、短く収まっていますが、少し分かりにくくなっています。

$ gawk -f cal.awk           # <- 今月のカレンダーです
    2009 / 06
SU MO TU WE TH FR SA
    1  2  3  4  5  6 
 7  8  9 10 11 12 13 
14 15 16 17 18 19 20 
21 22 23 24 25 26 27 
28 29 30 

$ gawk -f cal.awk 2010      # <- 2010 年の同じ月のカレンダーです
    2010 / 06
SU MO TU WE TH FR SA
       1  2  3  4  5 
 6  7  8  9 10 11 12 
13 14 15 16 17 18 19 
20 21 22 23 24 25 26 
27 28 29 30 

$ gawk -f cal.awk 1 2010    # <- 2010 年の 1 月のカレンダーです
    2010 / 01
SU MO TU WE TH FR SA
                1  2 
 3  4  5  6  7  8  9 
10 11 12 13 14 15 16 
17 18 19 20 21 22 23 
24 25 26 27 28 29 30 
31 

うるう年の判定は閏年 - jarp, あたりのものを使っても面白いかもしれませんが、条件演算子で判定しています。

cal コマンドの代用というよりは、ブログなどのパーツとして使えるかなと思い、1 ヶ月分の表示しかしていません。

tag_gawk.pngtag_gawk.png