こんな感じの関数が多分シンプル?
(defun jst-to-utc (time-str) (format-time-string "%Y-%m-%dT%H:%M:%S%z" (date-to-time time-str) 0)) (jst-to-utc "2025-02-04T21:57:14+09:00") ;; => "2025-02-04T12:57:14+0000"
M-x で呼び出し可能にするにはこう
(defun jst-to-utc (time-str) (interactive "sJST Time Str: ") (message (format-time-string "%Y-%m-%dT%H:%M:%S%z" (date-to-time time-str) 0)))
仕組み
Emacs で時刻を扱う際にはLispタイムスタンプという時刻をS式で表現する値を使う。
Time of Day (GNU Emacs Lisp Reference Manual)
例えば↑で変換した時刻をLispタイムスタンプ値にするとこうなる。
(date-to-time "2025-02-04 21:57:14+09:00") ;; => (26528 55792)
この値に対して format-time-string でフォーマットしてやると好きなタイムゾーンにできる
Time Parsing (GNU Emacs Lisp Reference Manual)
ちなみにLispタイムスタンプ値にから値を取るには decode-time という関数がある。時刻の値を細かく扱いたい場合はこの関数を使うとよさそう。
今回はLispタイムスタンプ値をそのまま別のタイムゾーンの文字列にフォーマットしたかったので登場しない*1。
Time Conversion (GNU Emacs Lisp Reference Manual)
(decode-time (date-to-time "2025-02-04 21:57:14+09:00")) ;; => (0 0 0 4 2 2025 2 nil 32400)
*1:最初 ChatGPT に聞いたらこれを使うコードを出されて混乱した