Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add a format specifier to `format-time-string`?

I have the following function definition:

(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))

and I'd like to be able to use it in format-time-string. Normally, I would look at the source of the function, but this one is defined in the C source code. (I would presume this precludes hooking something onto it, but I stand to be corrected.)

How can I add another format specifier (say, %o) that will apply nth to the appropriate argument?

Desired usage:

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

=> "Monday, August 17th, 20:00:00 (-0400)"
like image 463
Sean Allred Avatar asked Nov 01 '25 22:11

Sean Allred


2 Answers

Here is what you want to do. Stefan and Drew already gave some important remarks (don't overwrite nth and look at the info-files of emacs-lisp/advising functions).

(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))))

Notes:

  1. I did not handle the UNIVERSAL argument

  2. The hack does not work when format-time-string is called from C (as you can read in the manual).

like image 67
Tobias Avatar answered Nov 04 '25 10:11

Tobias


AFAIK you're out of luck: format-time-string does not offer any way to do that.

You might be able to work around this by using something like:

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

This said, I've always been told that "August 17th" is wrong: you're supposed to write "August 17" which is pronounced "August the seventheenth".

One more thing: nth is a predefined core function. Better not overwrite it with your own completely different definition.

like image 26
Stefan Avatar answered Nov 04 '25 08:11

Stefan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!