comparison lisp/calendar/time-date.el @ 91863:5f14edcf524f

(format-seconds): Remove `nonzero' argument in favor of `%z' specifier. (emacs-uptime): Move to time.el.
author Glenn Morris <rgm@gnu.org>
date Sat, 16 Feb 2008 03:30:28 +0000
parents f47b22aa9aac
children 870c7b456283
comparison
equal deleted inserted replaced
91862:af26df6df4a9 91863:5f14edcf524f
254 (date-to-time date) 254 (date-to-time date)
255 (error '(0 0)))) 255 (error '(0 0))))
256 256
257 257
258 ;;;###autoload 258 ;;;###autoload
259 (defun format-seconds (string seconds &optional nonzero) 259 (defun format-seconds (string seconds)
260 "Use format control STRING to format the number SECONDS. 260 "Use format control STRING to format the number SECONDS.
261 The valid format specifiers are: 261 The valid format specifiers are:
262 %y is the number of (365-day) years. 262 %y is the number of (365-day) years.
263 %d is the number of days. 263 %d is the number of days.
264 %h is the number of hours. 264 %h is the number of hours.
265 %m is the number of minutes. 265 %m is the number of minutes.
266 %s is the number of seconds. 266 %s is the number of seconds.
267 %z is a non-printing control flag (see below).
267 %% is a literal \"%\". 268 %% is a literal \"%\".
268 269
269 Upper-case specifiers are followed by the unit-name (e.g. \"years\"). 270 Upper-case specifiers are followed by the unit-name (e.g. \"years\").
270 Lower-case specifiers return only the unit. 271 Lower-case specifiers return only the unit.
271 272
272 \"%\" may be followed by a number specifying a width, with an 273 \"%\" may be followed by a number specifying a width, with an
273 optional leading \".\" for zero-padding. For example, \"%.3Y\" will 274 optional leading \".\" for zero-padding. For example, \"%.3Y\" will
274 return something of the form \"001 year\". 275 return something of the form \"001 year\".
275 276
276 If the optional argument NONZERO is non-nil, then nothing is output until 277 The \"%z\" specifier does not print anything. When it is used, specifiers
277 the first non-zero unit (or the last unit) is encountered. In this case, 278 must be given in order of decreasing size. To the left of \"%z\", nothing
278 specifiers must be used in order of decreasing size. 279 is output until the first non-zero unit is encountered.
279 280
280 This does not work for input SECONDS greater than `most-positive-fixnum'." 281 This function does not work for SECONDS greater than `most-positive-fixnum'."
281 (let ((start 0) 282 (let ((start 0)
282 (units '(("y" "year" 31536000) 283 (units '(("y" "year" 31536000)
283 ("d" "day" 86400) 284 ("d" "day" 86400)
284 ("h" "hour" 3600) 285 ("h" "hour" 3600)
285 ("m" "minute" 60) 286 ("m" "minute" 60)
286 ("s" "second" 1))) 287 ("s" "second" 1)
288 ("z")))
287 (case-fold-search t) 289 (case-fold-search t)
288 spec match outunits unit prev name num next) 290 spec match usedunits zeroflag larger prev name unit num zeropos)
289 (setq nonzero (not nonzero))
290 (while (string-match "%\\.?[0-9]*\\(.\\)" string start) 291 (while (string-match "%\\.?[0-9]*\\(.\\)" string start)
291 (setq start (match-end 0) 292 (setq start (match-end 0)
292 spec (match-string 1 string)) 293 spec (match-string 1 string))
293 (unless (string-equal spec "%") 294 (unless (string-equal spec "%")
294 (or (setq match (assoc-string spec units t)) 295 (or (setq match (assoc-string spec units t))
295 (error "Bad format specifier: `%s'" spec)) 296 (error "Bad format specifier: `%s'" spec))
296 (if (assoc-string spec outunits t) 297 (if (assoc-string spec usedunits t)
297 (error "Multiple instances of specifier: `%s'" spec)) 298 (error "Multiple instances of specifier: `%s'" spec))
298 (unless nonzero 299 (if (string-equal (car match) "z")
299 (setq unit (nth 2 match)) 300 (setq zeroflag t)
300 (and prev (> unit prev) 301 (unless larger
301 (error "Units are not in decreasing order of size")) 302 (setq unit (nth 2 match)
302 (setq prev unit)) 303 larger (and prev (> unit prev))
303 (push match outunits))) 304 prev unit)))
304 ;; Cf article-make-date-line in gnus-art. 305 (push match usedunits)))
305 (dolist (ulist units) 306 (and zeroflag larger
306 (setq spec (car ulist) 307 (error "Units are not in decreasing order of size"))
307 name (cadr ulist) 308 (dolist (u units)
308 unit (nth 2 ulist)) 309 (setq spec (car u)
310 name (cadr u)
311 unit (nth 2 u))
309 (when (string-match (format "%%\\(\\.?[0-9]+\\)?\\(%s\\)" spec) string) 312 (when (string-match (format "%%\\(\\.?[0-9]+\\)?\\(%s\\)" spec) string)
310 (setq num (floor seconds unit) 313 (if (string-equal spec "z") ; must be last in units
311 seconds (- seconds (* num unit))) 314 (setq string
312 (or nonzero 315 (replace-regexp-in-string
313 (setq nonzero (not (zerop num))) 316 "%z" ""
314 ;; Start of the next unit specifier, if there is one. 317 (substring string (min (or zeropos (match-end 0))
315 (setq next (save-match-data 318 (match-beginning 0)))))
316 (string-match "%\\.?[0-9]*[a-z]" 319 ;; Cf article-make-date-line in gnus-art.
317 string (match-end 0))))) 320 (setq num (floor seconds unit)
318 ;; If there are no more specifiers, we have to print this one, 321 seconds (- seconds (* num unit)))
319 ;; even if it is zero. 322 ;; Start position of the first non-zero unit.
320 (or nonzero (setq nonzero (not next))) 323 (or zeropos
321 (setq string 324 (setq zeropos (unless (zerop num) (match-beginning 0))))
322 (if nonzero 325 (setq string
323 (replace-match 326 (replace-match
324 (format (concat "%" (match-string 1 string) "d%s") num 327 (format (concat "%" (match-string 1 string) "d%s") num
325 (if (string-equal (match-string 2 string) spec) 328 (if (string-equal (match-string 2 string) spec)
326 "" ; lower-case, no unit-name 329 "" ; lower-case, no unit-name
327 (format " %s%s" name 330 (format " %s%s" name
328 (if (= num 1) "" "s")))) 331 (if (= num 1) "" "s"))))
329 t t string) 332 t t string))))))
330 ;; If we haven't found a non-zero unit yet, delete
331 ;; everything up to the next format specifier.
332 (substring string next))))))
333 (replace-regexp-in-string "%%" "%" string)) 333 (replace-regexp-in-string "%%" "%" string))
334 334
335
336 ;; This doesn't really belong here - perhaps in time.el?
337 ;;;###autoload
338 (defun emacs-uptime ()
339 "Return a string giving the uptime of this instance of Emacs."
340 (interactive)
341 (let ((str
342 (format-seconds "%Y, %D, %H, %M, %S"
343 (time-to-seconds
344 (time-subtract (current-time) emacs-startup-time))
345 t)))
346 (if (interactive-p)
347 (message "%s" str)
348 str)))
349 335
350 (provide 'time-date) 336 (provide 'time-date)
351 337
352 ;;; arch-tag: addcf07b-b20a-465b-af72-550b8ac5190f 338 ;;; arch-tag: addcf07b-b20a-465b-af72-550b8ac5190f
353 ;;; time-date.el ends here 339 ;;; time-date.el ends here