# 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!