2018-11-26 format-seconds

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!

CategoryEnglish, CategoryBlog, CategoryEmacs