Emacs の時刻表記が日本語から英語に変わる問題の解決法
1. はじめに
Emacs の org-mode のタイムスタンプが、 起動時は日本語表記だったのにもかかわらず、 Emacs 上で何らかの操作をすると英語表記に切り替わる問題が発生しました。
日本語では <2022-03-07 月>
のような表記で、
英語では <2022-03-07 Mon>
のような表記になります。
また、org-mode のタイムスタンプだけでなく Emacs 全体の時刻表示のロケールが変わってしまっているようで、 org-capture の date tree の曜日の表記や org-export したときの日付の表記も変わるため、 影響範囲は大きく地味に深刻な問題でした。
何をしたときに英語表記に切り替わるのかもよく分からない状態であったため、 一ヶ月程度放置していたのですがようやく暫定的な解決策を見つけたため紹介します。
2. いきなり結論
Emacs の設定に下記を追加することで解決します。
(setq system-time-locale nil)
3. 環境
下記のバージョンの Emacs で問題が生じました。
GNU Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.30, cairo version 1.16.0)
OS は GNU Guix System です。
4. 原因
emacs-org-contrib
パッケージの ox-rss
を利用した後に、
Emacs のタイムタンプの曜日が英語に切り替わることに気づきました。
調査をすすめたところ ox-rss.el
中の format-time-string
の実行後から英語に切り替わってしまうことが判明しました(該当箇所)。
Emacs 起動した後に上記のコードを基にして ielm(REPL)
で実験したところ、
一時的に system-time-locale
を C
に変更して format-time-string
を実行すると、
system-time-locale
が元の "ja"
に戻った後も曜日の表記が英語のままになってしまうことを確認しました
(なぜ下記の実行例で system-time-locale
を一時的に "C"
へ切り替えられるかについて気になる方は、Emacs Lisp のダイナミックスコープについて調べてください)
ELISP> system-time-locale "ja" ELISP> (format-time-string "%Y/%m/%d %A" '(24917 53488)) "2021/10/01 金曜日" ELISP> (let ((system-time-locale "C")) (format-time-string "%Y/%m/%d %A" '(24917 53488))) "2021/10/01 Friday" ELISP> system-time-locale "ja" ELISP> (format-time-string "%Y/%m/%d %A" '(24917 53488)) "2021/10/01 Friday" ELISP>
5. 解決法
Emacs の system-time-locale
変数のマニュアルを読んだ結果解決策を見つけられました。
system-time-locale
変数は下記のように説明されています。
This variable specifies the locale to use for formatting time values. Changing the locale can cause messages to appear according to the conventions of a different language. If the variable is nil, the locale is specified by environment variables in the usual POSIX fashion.
— https://www.gnu.org/software/emacs/manual/html_node/elisp/Locales.html から引用
system-time-locale
が nil
であればシステムの環境変数に従ってくれるようです。
私の環境の Emacs を起動した時点では system-time-locale
が "ja"
になっていて
なぜそのままだと機能しないのかについてはよく分からないのですが、
とりあえず nil
に設定しておけば、一度 system-time-locale
が "C"
の状態で
format-time-string
が呼び出されても日本語表記に戻ることを確認しました。
ELISP> (setq system-time-locale nil) nil ELISP> (format-time-string "%Y/%m/%d %A" '(24917 53488)) "2021/10/01 金曜日" ELISP> (let ((system-time-locale "C")) (format-time-string "%Y/%m/%d %A" '(24917 53488))) "2021/10/01 Friday" ELISP> system-time-locale nil ELISP> (format-time-string "%Y/%m/%d %A" '(24917 53488)) "2021/10/01 金曜日" ELISP>
というわけで Emacs の設定ファイルに下記を追加すれば解決です。
(setq system-time-locale nil)
6. おわりに
とてもマイナーな問題ですが、この記事が誰かを救うことになれば幸いです。