1 年の何分の一かを調べる

1年の何分の何が終わったかカレンダー - 西尾泰和のはてなダイアリー にインスパイヤされて、awk で 1 年の何分の一かを計算してみます。

純粋に nawk だけでも解けないわけではないのですが、時間を扱う関数が gawk に用意されていますので、これを用いて解きます。

  • mktime() 関数を用いるとエポック時間に変換できます。
  • エポック時間を strftime() 関数の第 2 引数に入れることで日時に変換することができます。
#! /usr/local/bin/gawk -f
# div_year.awk

BEGIN {
    num_div = ARGV[1] ? ARGV[1] : 10;

    year        = strftime("%Y");
    next_year   = year + 1;

    start_epoch = mktime(year      " 01 01 00 00 00");
    end_epoch   = mktime(next_year " 01 01 00 00 00");

    span = end_epoch - start_epoch;

    for (i = 2; i <= num_div; i++) {
        for (j = 1; j <= i - 1; j++) {
            elapse  = int(span / i * j);
            date    = strftime("%Y-%m-%d", start_epoch + elapse);

            div_of[date] = div_of[date] " " j "/" i;
        }
    }

    PROCINFO["sorted_in"] = "@ind_str_asc";

    for (i in div_of) {
        print i " " div_of[i];
    }
}

任意の分割数を指定する場合には引数に分割数を入れれば計算できます。 gawk4 の機能として環境変数 PROCINFO でソートする順序を指定しています。

では、実行してみましょう。

$ gawk -f div_year.awk
2013-02-06  1/10
2013-02-10  1/9
2013-02-15  1/8
2013-02-22  1/7
2013-03-02  1/6
2013-03-15  1/5 2/10
2013-03-23  2/9
2013-04-02  1/4 2/8
2013-04-15  2/7
2013-04-20  3/10
2013-05-02  1/3 2/6 3/9
2013-05-17  3/8
2013-05-27  2/5 4/10
2013-06-06  3/7
2013-06-12  4/9
2013-07-02  1/2 2/4 3/6 4/8 5/10
2013-07-22  5/9
2013-07-28  4/7
2013-08-08  3/5 6/10
2013-08-17  5/8
2013-09-01  2/3 4/6 6/9
2013-09-13  7/10
2013-09-18  5/7
2013-10-01  3/4 6/8
2013-10-11  7/9
2013-10-20  4/5 8/10
2013-11-01  5/6
2013-11-09  6/7
2013-11-16  7/8
2013-11-21  8/9
2013-11-25  9/10

実行できましたね。

以下のようにして遊ぶこともできます。

$ gawk -f div_year.awk 1000 | gawk '$1~strftime("%Y-%m-%d") && $0=$1'
2013-03-01

$ gawk -f div_year.awk 1000 | gawk '$1~strftime("%Y-%m-%d") && $0=$2'
6/37

$ gawk -f div_year.awk 1000 | gawk '$1~strftime("%Y-%m-%d") && $0=$NF'
164/1000

つまり、今日 (2013-03-01) は 2013 年の 6/37 で、16.4 % ということになります。

tag_gawk.png