Lisp's format
function has the directive ~/
that calls the specified function to process the argument.
For example,
(defun format-date (stream universal-time colon-modifier-p at-sign-modifier-p)
(declare (ignore colon-modifier-p at-sign-modifier-p))
(multiple-value-bind (seconds minutes hours day month year) (decode-universal-time universal-time)
(format stream "~4,'0D-~2,'0D-~2,'0D ~2,'0D:~2,'0D:~2,'0D" year month day hours minutes seconds)))
(defun format-duration (stream seconds colon-modifier-p at-sign-modifier-p)
(declare (ignore colon-modifier-p at-sign-modifier-p))
(let ((seconds (mod (truncate seconds) 60))
(minutes (mod (truncate seconds 60) 60))
(hours (truncate seconds 3600))
(milliseconds (truncate (mod (* seconds 1000) 1000))))
(format stream "~2,'0D:~2,'0D:~2,'0D.~3,'0D" hours minutes seconds milliseconds)))
(format stream "Start: ~/ir-snowball::format-date/,
end: ~/ir-snowball::format-date/,
duration ~/ir-snowball::format-duration/."
start-time (get-universal-time) (- (get-universal-time) start-time))
This will print “Start: 2008-10-14 23:39:10, end: 2008-10-14 23:40:57, duration 00:01:47.000”.