大体の時刻を表示するコマンド

だいたいの時刻を表示するコマンド - みずぴー日記にインスパイヤされているわけですが、元の記事はだいたいの時間が分かる時計 NEXTIME/Word Clock こだわりやさんの日記の時計です。

この時計ですが、全ての表記を読み取ることはできませんが、

  • 5 分刻み
  • 30 分までは "past"
  • 30 分以降は "before" (であろう)
  • 15 分は "a quater" ("a" が入る)
  • 0 分は "It's about"

ということが分かります。

基本的に gawk の時間関数を用いて、文字列は配列に格納してあるものを使うことにします。

#! /usr/local/bin/gawk -f
# about_clock.awk
# 大体の時間を表示する
# usage: gawk -f about_clock.awk

BEGIN {
    hour_str = "one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve";
    min_str  = "It's about,five minutes past,ten minutes past,a quater past,"\
               "twenty minutes past,twenty-five minutes past,half past";

    hour = hour ? hour : strftime("%I") + 0;
    min  = min  ? min  : strftime("%M") + 0;

    split(hour_str, arr_hour_str, /,/);
    split(min_str,  arr_min_str,  /,/);

    if (min < 59) {
        min_call = arr_min_str[1];
        new_hour = (hour + 1) > 12 ? 1 : hour + 1;
    }
    if (min < 57) {
        min_call = gensub(/past/, "before", 1, arr_min_str[2]);
        new_hour = (hour + 1) > 12 ? 1 : hour + 1;
    }
    if (min < 52) {
        min_call = gensub(/past/, "before", 1, arr_min_str[3]);
        new_hour = (hour + 1) > 12 ? 1 : hour + 1;
    }
    if (min < 47) {
        min_call = gensub(/past/, "before", 1, arr_min_str[4]);
        new_hour = (hour + 1) > 12 ? 1 : hour + 1;
    }
    if (min < 42) {
        min_call = gensub(/past/, "before", 1, arr_min_str[5]);
        new_hour = (hour + 1) > 12 ? 1 : hour + 1;
    }
    if (min < 37) {
        min_call = gensub(/past/, "before", 1, arr_min_str[6]);
        new_hour = (hour + 1) > 12 ? 1 : hour + 1;
    }
    if (min < 32) {
        min_call = gensub(/past/, "before", 1, arr_min_str[7]);
        new_hour = (hour + 1) > 12 ? 1 : hour + 1;
    }
    if (min < 27) {
        min_call = arr_min_str[6];
        new_hour = hour;
    }
    if (min < 22) {
        min_call = arr_min_str[5];
        new_hour = hour;
    }
    if (min < 17) {
        min_call = arr_min_str[4];
        new_hour = hour;
    }
    if (min < 12) {
        min_call = arr_min_str[3];
        new_hour = hour;
    }
    if (min < 7) {
        min_call = arr_min_str[2];
        new_hour = hour;
    }
    if (min < 2) {
        min_call = arr_min_str[1];
        new_hour = hour;
    }

    # strftime("%I") では 0 時は 12 と返るため、そのまま使う
    hour_call = arr_hour_str[new_hour];

    print min_call " " hour_call;
}

冗長な if 文になっていますが、どこを区切りにしたらいいか分からなかったので、if 文の羅列にしています。

$ gawk -f about_clock.awk
half before two

一応、デバッグ用に時間指定ができます。

$ gawk -v hour=11 -v min=5 -f about_clock.awk
five minutes past eleven

$ gawk -v hour=11 -v min=55 -f about_clock.awk
five minutes before twelve

時刻に関するものはデバッグ用のものを用意しておかないと、デバッグするのに、その時刻を待たなければならないため面倒です。

tag_gawk.pngtag_gawk.png