If you’ve ever done anything UI- and time-related in Elisp (or whatever language), chances are that you did stuff like
(defun format-minutes (minutes) "Format MINUTES in a human-friendly way." (if (< minutes 60) (format "%dmin" minutes) (let ((h (/ minutes 60)) (min (mod minutes 60))) (if (zerop min) (format "%dh" h) (format "%dh %dmin" h min)))))
It turns out that you really don’t have to (at least assuming that you don’t mind to see 4h 0min
instead of just 4h
). I learned about a nice Elisp function format-seconds
, which accepts a format string and a number of seconds and outputs the value of that time converted to things like 2 days, 1 hour, 21 minutes, 57 seconds
. The format specifiers are the usual %y
, %d
, %h
etc., with two twists. One is that capital letters mean producing the value with the unit (in English – notice that the unit is in correct grammar form, singular or plural). The other is that you can put a %z
flag somewhere in the format, and that means “don’t print anything up to this point if all values to the left of %z
are zero”. (This makes an assumption that all specifiers are given in the order of decreasing size – but the function actually checks for that.) In other words, (format-seconds
"%H, %M and%z %S" 12345)
produces 3 hours, 25 minutes and 45
seconds
, (format-seconds "%H, %M and %z%S" 123)
produces 2 minutes
and 3 seconds
, and (format-seconds "%H, %M and%z %S" 12)
produces 12 seconds
, while the corresponding second arguments with the format string of "%h:%z%.2m:%.2s"
will yield 3:25:45
, 02:03
, 00:12
respectively (the .2
means “left-pad with zeroes to 2 characters”).
Very nice!