$ cal
3月 2025
日 月 火 水 木 金 土
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
5 月なのに 3 月と言われる。
$ date #午後
date で #午後 という文字列が返ってくる。
状況は cal -y するとある程度理解できて、
$ cal -y | grep "[0-9]月"
PM %Y年 %B%e日 %A %X %Z 1月
2月 3月 4月
5月 6月 7月
8月 9月 10月
と、本来「1月」「2月」となるべきところに「PM」「%Y年 %B%e日 %A %X %Z」が入り込んでいる。どこかで何らかのズレが生じているのだろう。
どうやら日本語だけの問題っぽく、LANG を変えると正常に出力される。
$ LANG=C cal
May 2025
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
$ LANG=C date Thu May 22 02:01:25 JST 2025
これはもう LOCALE の問題であろう。と /usr/share/locale/ 以下を眺めると、ja_JP.UTF-8 を含むいくつかの言語ファイルで行数が違うのが見える。
$ wc -l /usr/share/locale/*.UTF-8/LC_TIME
...
58 /usr/share/locale/is_IS.UTF-8/LC_TIME
58 /usr/share/locale/it_CH.UTF-8/LC_TIME
58 /usr/share/locale/it_IT.UTF-8/LC_TIME
60 /usr/share/locale/ja_JP.UTF-8/LC_TIME
58 /usr/share/locale/kk_KZ.UTF-8/LC_TIME
60 /usr/share/locale/ko_KR.UTF-8/LC_TIME
58 /usr/share/locale/lt_LT.UTF-8/LC_TIME
58 /usr/share/locale/lv_LV.UTF-8/LC_TIME
58 /usr/share/locale/mn_MN.UTF-8/LC_TIME
...
en_US.UTF-8 と ja_JP.UTF-8 を見比べると、確かにおかしい。
$ cat -n /usr/share/locale/en_US.UTF-8/LC_TIME
...
38 Saturday
39 %H:%M:%S
40 %m/%d/%Y
41 %a %b %e %X %Y
42 AM
43 PM
44 %a %b %e %X %Z %Y
45 January
46 February
47 March
...
$ cat -n /usr/share/locale/ja_JP.UTF-8/LC_TIME
...
38 土曜日
39 %H時%M分%S秒
40 %Y/%m/%d
41 %a %b/%e %T %Y
42 #午前
43 AM
44 #午後
45 PM
46 %Y年 %B%e日 %A %X %Z
47 1月
...
先ほど cal -y で出力されていたのもこの 45 行目、46 行目ですね。
じゃあ /usr/share/locale/ja_JP.UTF-8/LC_TIME を書き換えたら直るんじゃないかと思ったら sudo でも編集できない。SIP (System Integrity Protection) によって守られてるんだった。
ここまで見て「面白い〜」と社の Slack で共有したところ、
id:KashEight から「man setlocale が参考になりそう?」という反応を貰った。
$ man setlocale
...
FILES
$PATH_LOCALE/locale/category
/usr/share/locale/locale/category locale file for the locale locale and the category category.
/usr/local/share/locale/locale/category
locale file for the locale locale and the category category.
...
環境変数 $PATH_LOCALE を見ているので、リカバリーモードで無理矢理 /usr/share/locale/ 以下を書き換えなくてもどうにかなりそう。
$HOME/.config/locale/ 以下に ja_JP.UTF-8/ をまるっとコピーして、LC_TIME を弄る。
$ diff -u {/usr/share,$HOME/.config}/locale/ja_JP.UTF-8/LC_TIME
--- /usr/share/locale/ja_JP.UTF-8/LC_TIME 2025-04-12 14:16:09
+++ /Users/onaka/.config/locale/ja_JP.UTF-8/LC_TIME 2025-05-17 13:51:58
@@ -39,10 +39,8 @@
%H時%M分%S秒
%Y/%m/%d
%a %b/%e %T %Y
-#午前
-AM
-#午後
-PM
+午前
+午後
%Y年 %B%e日 %A %X %Z
1月
2月
環境変数を設定して、cal や date を打つと……
$ export PATH_LOCALE=$HOME/.config/locale
$ cal
5月 2025
日 月 火 水 木 金 土
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
$ date
2025年 5月22日 木曜日 02時19分11秒 JST
やったぜ!
以下のディスカッションも見つけました。Sequoia 15.4 以降のバグっぽいのでフィードバックしておきましょう。先日出た 15.5 でも直ってない!