これは「タイムラボ Advent Calendar 2024」の 7 日目の記事です。 https://adventar.org/calendars/10585
はじめに
前回 に引き続いて、今年初の投稿です。
今年も、業務委託で一緒にお仕事をさせていただいている 株式会社タイムラボ のアドベントカレンダーに参加することになりました!
タイムラボにはエンジニアとして参画しており、フロントエンドとバックエンドを担当しています!
今回、色々何を書くか悩んだのですが、普段カレンダーのアプリケーション開発に携わっている者として知っておくべき、自分が知っている中で最古カレンダーソフトウェア cal
コマンドを紹介したいと思います!
なるべくエンジニア以外の方も読めるように、噛み砕いて説明していますので、最後まで読んでいただけると嬉しいです!
なお、筆者は MacOS を利用しているので、今回の記事では GNU 版ではなく、BSD(FreeBSD)版を取り扱います。
cal
コマンドとは
cal
コマンドは、いわゆる Linux コマンドの一種で、ターミナル上にカレンダーを表示するコマンドです。
引数を何も渡さずに実行すると、今月のカレンダーを表示します。
$ cal
12月 2024
日 月 火 水 木 金 土
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
その歴史は古く、man
コマンド(コマンドのマニュアルを表示するコマンド)の HISTORY を確認すると、
A cal command appeared in Version 1 AT&T UNIX.
と記載があるので、1971 年頃(半世紀以上前)に登場したことが分かります。
なお、cal
を更に拡張した、後発の ncal
コマンドも存在します。
こちらは cal
よりもオプションが多いのに加え、デフォルトの月の表示形式が縦向きになっています。
$ ncal
12月 2024
月 2 9 16 23 30
火 3 10 17 24 31
水 4 11 18 25
木 5 12 19 26
金 6 13 20 27
土 7 14 21 28
日 1 8 15 22 29
これらのコマンドは柔軟に切り替えることができ、cal
に -N
オプションを付けると ncal
に、逆に ncal
に -C
オプションを付けると cal
に切り替えることができます。
$ cal -N
12月 2024
月 2 9 16 23 30
火 3 10 17 24 31
水 4 11 18 25
木 5 12 19 26
金 6 13 20 27
土 7 14 21 28
日 1 8 15 22 29
$ ncal -C
12月 2024
日 月 火 水 木 金 土
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
また、これは cal
コマンドだけ特殊なのですが、少なくとも 1 つの文字を大文字にして実行すると、ncal
に切り替わります。
$ Cal
12月 2024
月 2 9 16 23 30
火 3 10 17 24 31
水 4 11 18 25
木 5 12 19 26
金 6 13 20 27
土 7 14 21 28
日 1 8 15 22 29
様々なオプション
cal
には様々なオプションが存在しますが、ここでは一部のみを紹介します。
ぜひこの記事を読んでいる方もターミナルを立ち上げて、実際に実行してみると面白いと思います(MacOS の場合はデフォルトでインストールされてます)!
ある年のカレンダーを表示する
cal
コマンドに直接数字(1 ~ 9999)を渡すと、その年のカレンダーを表示します。
たとえば、$ cal 1
($ cal -y 1
)を実行すると、西暦 1 年のカレンダーが表示されます。
年は -y
オプションで渡すことも可能です。
(場所を取るので出力結果は省略します…)
ある年月のカレンダーを表示する
cal
に 2 つの数字を直接渡すと、1 つ目の数字を月、2 つ目の数字を年とするカレンダーを表示します。
$ cal 2 1994
2月 1994
日 月 火 水 木 金 土
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
月は -m
オプションで渡すことが可能なため、$ cal -m 2 1994
を実行しても、上記の結果を得ることができます。
ただし、-y
と -m
を同時に利用することはできません。
$ cal -m 2 -y 1994
cal: -y together with -m is not supported.
先月と次月のカレンダーも一緒に表示する
-3
オプションをつけると、先月と今月、次月の 3 つのカレンダーをまとめて表示することができます。
$ cal -3
11月 2024 12月 2024 1月 2025
日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土
1 2 1 2 3 4 5 6 7 1 2 3 4
3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
24 25 26 27 28 29 30 29 30 31
現在の月の後(前)に続く月数を指定して表示
-A
オプションに数字を渡すと、現在の月に続く指定した個数分の月が表示されます。
$ cal -A 1
12月 2024 1月 2025
日 月 火 水 木 金 土 日 月 火 水 木 金 土
1 2 3 4 5 6 7 1 2 3 4
8 9 10 11 12 13 14 5 6 7 8 9 10 11
15 16 17 18 19 20 21 12 13 14 15 16 17 18
22 23 24 25 26 27 28 19 20 21 22 23 24 25
29 30 31 26 27 28 29 30 31
同様に -B
オプションに数字を渡すと、現在の月の前の指定した個数分の月が表示されます。
$ cal -B 1
11月 2024 12月 2024
日 月 火 水 木 金 土 日 月 火 水 木 金 土
1 2 1 2 3 4 5 6 7
3 4 5 6 7 8 9 8 9 10 11 12 13 14
10 11 12 13 14 15 16 15 16 17 18 19 20 21
17 18 19 20 21 22 23 22 23 24 25 26 27 28
24 25 26 27 28 29 30 29 30 31
これらのオプションは組み合わせることもできるため、-A
と -B
にそれぞれ 1 を指定すると、-3
を指定した場合と同じ結果を得ることができます。
$ cal -A 1 -B 1
11月 2024 12月 2024 1月 2025
日 月 火 水 木 金 土 日 月 火 水 木 金 土 日 月 火 水 木 金 土
1 2 1 2 3 4 5 6 7 1 2 3 4
3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
24 25 26 27 28 29 30 29 30 31 26 27 28 29 30 31
グレゴリオ暦への切り替えの考慮
話は変わりますが、現在我々が使っている西暦は グレゴリオ暦 であり、1582 年 10 月にローマ教皇 グレゴリウス 13 世 によって導入されたものです。
導入された意図としては、それまで採用されていた ユリウス暦 と 実際の 太陽年 との誤差を埋めるためです。
この導入により、10 月の日付は 11 日繰り上がり、10/4(木) の次は 10/15(金) となっていました。
ncal
コマンドでもこのことは考慮されており、-p
オプションをつけると、各国の暦がどのタイミングでグレゴリオ暦に切り替わったかを確認することができます。
$ ncal -p
AL Albania 1912-11-30 IS Iceland 1700-11-16
AT Austria 1583-10-05 IT Italy 1582-10-04
...(省略)...
また、-s
で国名コード(上記の -p
で表示される 2 つの大文字アルファベット)を指定するとその国のカレンダーを確認することができます。
たとえばイタリア(IT
)を指定すると、 1582 年 10 月のカレンダーは以下のようになっており、切り替わっているのを確認できます。
$ ncal -s IT 10 1582
10月 1582
月 1 18 25
火 2 19 26
水 3 20 27
木 4 21 28
金 15 22 29
土 16 23 30
日 17 24 31
日本のグレゴリオ暦の導入
日本では 1872 年(明治 5 年) 12 月 2 日に既存の 天保暦 を廃止し、グレゴリオ暦を導入しました(明治改暦)。
これにより、12 月 2 日の次が 1873 年元旦になりました。
ncal
でもこのことは考慮されているはずですが、ncal -p
で確認すると以下のように 1918-12-18
と記載されています。
$ ncal -p
AL Albania 1912-11-30 IS Iceland 1700-11-16
AT Austria 1583-10-05 IT Italy 1582-10-04
AU Australia 1752-09-02 JP Japan 1918-12-18
...(省略)...
実際に 1872 年 12 月のカレンダーを見ても、日付は飛んでいませんでした。
$ ncal -s JP 12 1872
12月 1872
月 4 11 18 25
火 5 12 19 26
水 6 13 20 27
木 7 14 21 28
金 1 8 15 22 29
土 2 9 16 23 30
日 3 10 17 24 31
逆に 1918 年 12 月のカレンダーを見ると、日付が飛んでいるのが確認できます。
$ ncal -s JP 12 1918
12月 1918
月 3 10 17
火 4 11 18
水 5 12
木 6 13
金 7 14
土 1 8 15
日 2 9 16
何故この日付になっているのか全く理由が分からなかったので、もしこの記事をご覧の方で分かる方が居ましたら、筆者の X まで連絡をいただけますと幸いです 🙇
追記 ①
同じような疑問を持って、深堀りした方のブログ記事を見つけたので参考に掲載します。
https://memo.furyutei.com/entry/20150213/1423824322
所感
最後まで見ていただいてありがとうございました。
相変わらず誰向けの記事かいまいち分かりませんが、少しでも楽しんでいただけたら幸いです。
cal
/ ncal
コマンドの存在自体は前から知っていたのですが、利用するシーンもなかなか無かったので、今回改めて色々調べることで、豊富なオプションがあったり、一部トリッキーな動作があったりと様々な発見があって面白かったです。
今回は FreeBSD 版のみ触ったので、次回は GNU 版も触ってみたり、実際に公開されているコマンドの実装 を解読してみようと思います。