如何在`format-time-string`中添加格式说明符?

时间:2013-12-01 20:19:11

标签: emacs elisp format-string

我有以下功能定义:

(defun nth (n)
  (format
   (concat
    "%d"
    (if (memq n '(11 12 13)) "th"
      (let ((last-digit (% n 10)))
        (case last-digit
          (1 "st")
          (2 "nd")
          (3 "rd")
          (otherwise "th"))))) n))

我希望能够在format-time-string中使用它。 通常,我会查看函数的来源,但这个是在C源代码中定义的。 (我认为这可以排除在上面挂东西,但我有待纠正。)

如何添加另一个格式说明符(例如%o),将nth应用于相应的参数?

所需用法:

(format-time-string "%A, %B %o, %T (%z)" (seconds-to-time 1250553600))

=> "Monday, August 17th, 20:00:00 (-0400)"

3 个答案:

答案 0 :(得分:3)

这是你想要做的。 Stefan和Drew已经发表了一些重要的评论(不要覆盖nth并查看emacs-lisp / advising函数的信息文件。)

(defun ordinal (n)
  "Special day of month format."
  (format
   (concat
    "%d"
    (if (memq n '(11 12 13)) "th"
      (let ((last-digit (% n 10)))
        (case last-digit
          (1 "st")
          (2 "nd")
          (3 "rd")
          (otherwise "th"))))) n))


(defadvice format-time-string (before ordinal activate)
  "Add ordinal to %d."
  (let ((day (nth 3 (decode-time (or time (current-time))))))
    (setq format-string
      (replace-regexp-in-string "%o"
                    (ordinal day)
                    format-string))))

注意:

  1. 我没有处理UNIVERSAL参数

  2. 从C调用format-time-string时,hack不起作用(正如您在本手册中所述)。

答案 1 :(得分:1)

AFAIK你运气不好:format-time-string没有提供任何办法。

您可以使用以下内容解决此问题:

(let ((ti (seconds-to-time 1250553600)))
 (format-time-string (concat "%A, %B " (my-nth (format-time-string "%d" ti)) ", %T (%z)") ti))

这就是说,我总是被告知“8月17日”是错的:你应该写“8月17日”,发音为“8月7日”。

还有一件事:nth是预定义的核心功能。最好不要用你自己完全不同的定义覆盖它。

答案 2 :(得分:1)

添加斯特凡说的话(“你运气不好”) -

format-time-string是内置的,但您也可以建议内置插件。但是,由于您想要做的手术会深入到定义的内容中(您无法做到),您实际上需要替换format-time-string的定义。 defadvice,即根本不使用ad-do-it

换句话说,在Lisp中,您需要以某种方式(defundefadvice)完全重新定义函数。这与说“你运气不好”大致相同。