aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorPaul Eggert2019-08-20 17:34:03 -0700
committerPaul Eggert2019-08-20 17:36:46 -0700
commit396ed88a50fba95cd3b989965defef0130a42c42 (patch)
tree95b03c537acf8d65b6d894a283eccf9f1d31a1e8 /lisp
parent7e2090ee80c9099ee953392444e1d73d10e973d4 (diff)
downloademacs-396ed88a50fba95cd3b989965defef0130a42c42.tar.gz
emacs-396ed88a50fba95cd3b989965defef0130a42c42.zip
Avoid some excess precision in time arithmetic
* doc/misc/emacs-mime.texi (time-date): Adjust example to match new behavior. * etc/NEWS: Mention this. * lisp/calendar/time-date.el (decoded-time-add) (decoded-time--alter-second): Don’t lose underestimate precision of seconds component. * src/bignum.c (mpz): Grow by 1. * src/timefns.c (trillion_factor): New function. (timeform_sub_ps_p): Remove. (time_arith): Avoid unnecessarily-large hz, by reducing the hz to a value no worse than the worse hz of the two arguments. The result is always exact unless an error is signaled. * test/src/timefns-tests.el (timefns-tests--decode-time): New function. (format-time-string-with-zone): Test (decode-time LOOK ZONE t) resolution as well as its numeric value.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/calendar/time-date.el32
1 files changed, 21 insertions, 11 deletions
diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index f3d252f03c6..11bd469ae3b 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -421,10 +421,13 @@ changes in daylight saving time are not taken into account."
421 ;; Do the time part, which is pretty simple (except for leap 421 ;; Do the time part, which is pretty simple (except for leap
422 ;; seconds, I guess). 422 ;; seconds, I guess).
423 ;; Time zone adjustments are basically the same as time adjustments. 423 ;; Time zone adjustments are basically the same as time adjustments.
424 (setq seconds (time-add (+ (* (or (decoded-time-hour delta) 0) 3600) 424 (setq seconds (time-convert (or (decoded-time-second delta) 0) t))
425 (* (or (decoded-time-minute delta) 0) 60) 425 (setq seconds
426 (or (decoded-time-zone delta) 0)) 426 (time-add seconds
427 (or (decoded-time-second delta) 0))) 427 (time-convert (+ (* (or (decoded-time-hour delta) 0) 3600)
428 (* (or (decoded-time-minute delta) 0) 60)
429 (or (decoded-time-zone delta) 0))
430 (cdr seconds))))
428 431
429 (decoded-time--alter-second time seconds) 432 (decoded-time--alter-second time seconds)
430 time)) 433 time))
@@ -461,11 +464,16 @@ changes in daylight saving time are not taken into account."
461 464
462(defun decoded-time--alter-second (time seconds) 465(defun decoded-time--alter-second (time seconds)
463 "Increase the time in TIME by SECONDS." 466 "Increase the time in TIME by SECONDS."
464 (let* ((secsperday 86400) 467 (let* ((time-sec (time-convert (or (decoded-time-second time) 0) t))
465 (old (time-add (+ (* 3600 (or (decoded-time-hour time) 0)) 468 (time-hz (cdr time-sec))
466 (* 60 (or (decoded-time-minute time) 0))) 469 (old (time-add time-sec
467 (or (decoded-time-second time) 0))) 470 (time-convert
468 (new (time-add old seconds))) 471 (+ (* 3600 (or (decoded-time-hour time) 0))
472 (* 60 (or (decoded-time-minute time) 0)))
473 time-hz)))
474 (new (time-convert (time-add old seconds) t))
475 (new-hz (cdr new))
476 (secsperday (time-convert 86400 new-hz)))
469 ;; Hm... DST... 477 ;; Hm... DST...
470 (while (time-less-p new 0) 478 (while (time-less-p new 0)
471 (decoded-time--alter-day time nil) 479 (decoded-time--alter-day time nil)
@@ -474,8 +482,10 @@ changes in daylight saving time are not taken into account."
474 (decoded-time--alter-day time t) 482 (decoded-time--alter-day time t)
475 (setq new (time-subtract new secsperday))) 483 (setq new (time-subtract new secsperday)))
476 (let ((sec (time-convert new 'integer))) 484 (let ((sec (time-convert new 'integer)))
477 (setf (decoded-time-second time) (time-add (% sec 60) 485 (setf (decoded-time-second time) (time-add
478 (time-subtract new sec)) 486 (time-convert (% sec 60) new-hz)
487 (time-subtract
488 new (time-convert sec new-hz)))
479 (decoded-time-minute time) (% (/ sec 60) 60) 489 (decoded-time-minute time) (% (/ sec 60) 60)
480 (decoded-time-hour time) (/ sec 3600))))) 490 (decoded-time-hour time) (/ sec 3600)))))
481 491