diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2014-11-16 20:38:15 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2014-11-16 20:41:22 -0800 |
commit | 0921dbc3ab4dcc6b291ef45e46a24b322bbcb885 (patch) | |
tree | 0e320978c7d30af415bb7de6e0b8f6735a3ca3d1 /lisp/calendar | |
parent | 058f56d24f776bdc25bcac86fe1f8969a78374e9 (diff) | |
download | emacs-0921dbc3ab4dcc6b291ef45e46a24b322bbcb885.tar.gz |
Improve time stamp handling, and be more consistent about it.
This implements a suggestion made in:
http://lists.gnu.org/archive/html/emacs-devel/2014-10/msg00587.html
Among other things, this means timer.el no longer needs to
autoload the time-date module.
* doc/lispref/os.texi (Time of Day, Time Conversion, Time Parsing)
(Processor Run Time, Time Calculations):
Document the new behavior, plus be clearer about the old behavior.
(Idle Timers): Take advantage of new functionality.
* etc/NEWS: Document the changes.
* lisp/allout-widgets.el (allout-elapsed-time-seconds): Doc fix.
* lisp/arc-mode.el (archive-ar-summarize):
* lisp/calendar/time-date.el (seconds-to-time, days-to-time, time-since):
* lisp/emacs-lisp/timer.el (timer-relative-time, timer-event-handler)
(run-at-time, with-timeout-suspend, with-timeout-unsuspend):
* lisp/net/tramp.el (tramp-time-less-p, tramp-time-subtract):
* lisp/proced.el (proced-time-lessp):
* lisp/timezone.el (timezone-time-from-absolute):
* lisp/type-break.el (type-break-schedule, type-break-time-sum):
Simplify by using new functionality.
* lisp/calendar/cal-dst.el (calendar-next-time-zone-transition):
Do not return time values in obsolete and undocumented (HI . LO)
format; use (HI LO) instead.
* lisp/calendar/time-date.el (with-decoded-time-value):
Treat 'nil' as current time. This is mostly for XEmacs.
(encode-time-value, with-decoded-time-value): Obsolete.
(time-add, time-subtract, time-less-p): Use no-op autoloads, for
XEmacs. Define only if XEmacs, as they're now C builtins in Emacs.
* lisp/ldefs-boot.el: Update to match new time-date.el
* lisp/proced.el: Do not require time-date.
* src/editfns.c (invalid_time): New function.
Use it instead of 'error ("Invalid time specification")'.
(time_add, time_subtract, time_arith, Ftime_add, Ftime_less_p)
(decode_float_time, lisp_to_timespec, lisp_time_struct):
New functions.
(make_time_tail, make_time): Remove. All uses changed to use
new functions or plain list4i.
(disassemble_lisp_time): Return effective length if successful.
Check that LOW is an integer, if it's combined with other components.
(decode_time_components): Decode into struct lisp_time, not
struct timespec, so that we can support a wide set of times
regardless of whether time_t is signed. Decode plain numbers
as seconds since the Epoch, and nil as the current time.
(lisp_time_argument, lisp_seconds_argument, Ffloat_time):
Reimplement in terms of new functions.
(Fencode_time): Just use list2i.
(syms_of_editfns): Add time-add, time-subtract, time-less-p.
* src/keyboard.c (decode_timer): Don't allow the new formats (floating
point or nil) in timers.
* src/systime.h (LO_TIME_BITS): New constant. Use it everywhere in
place of the magic number '16'.
(struct lisp_time): New type.
(decode_time_components): Use it.
(lisp_to_timespec): New decl.
Diffstat (limited to 'lisp/calendar')
-rw-r--r-- | lisp/calendar/cal-dst.el | 1 | ||||
-rw-r--r-- | lisp/calendar/time-date.el | 158 |
2 files changed, 76 insertions, 83 deletions
diff --git a/lisp/calendar/cal-dst.el b/lisp/calendar/cal-dst.el index e3cb690306e..2a9cdee301d 100644 --- a/lisp/calendar/cal-dst.el +++ b/lisp/calendar/cal-dst.el @@ -179,6 +179,7 @@ Return nil if no such transition can be found." (if (eq (car (current-time-zone probe)) hi-utc-diff) (setq hi probe) (setq lo probe))) + (setcdr hi (list (cdr hi))) hi)))) (autoload 'calendar-persian-to-absolute "cal-persia") diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 82bc05f299f..100e856469a 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -30,10 +30,9 @@ ;; value equal to HIGH * 2^16 + LOW + USEC * 10^-6 + PSEC * 10^-12 ;; seconds, where missing components are treated as zero. HIGH can be ;; negative, either because the value is a time difference, or because -;; the machine supports negative time stamps that fall before the epoch. -;; The macro `with-decoded-time-value' and the function -;; `encode-time-value' make it easier to deal with these formats. -;; See `time-subtract' for an example of how to use them. +;; it represents a time stamp before the epoch. Typically, there are +;; more time values than the underlying system time type supports, +;; but the reverse can also be true. ;;; Code: @@ -71,6 +70,7 @@ list (HIGH LOW MICRO PICO)." ,low ,micro) (when pico `(,pico)) (when type `(,type))) + (or ,gensym (setq ,gensym (current-time))) (if (consp ,gensym) (progn (setq ,low (pop ,gensym)) @@ -108,6 +108,10 @@ it is assumed that PICO was omitted and should be treated as zero." ((eq type 3) (list high low micro pico)) ((null type) (encode-time-value high low micro 0 pico)))) +(when (featurep 'emacs) + (make-obsolete 'encode-time-value nil "25.1") + (make-obsolete 'with-decoded-time-value nil "25.1")) + (autoload 'parse-time-string "parse-time") (autoload 'timezone-make-date-arpa-standard "timezone") @@ -158,47 +162,17 @@ TIME defaults to the current time." ;;;###autoload (defun seconds-to-time (seconds) - "Convert SECONDS (a floating point number) to a time value." - (let* ((usec (* 1000000 (mod seconds 1))) - (ps (round (* 1000000 (mod usec 1)))) - (us (floor usec)) - (lo (floor (mod seconds 65536))) - (hi (floor seconds 65536))) - (if (eq ps 1000000) - (progn - (setq ps 0) - (setq us (1+ us)) - (if (eq us 1000000) - (progn - (setq us 0) - (setq lo (1+ lo)) - (if (eq lo 65536) - (progn - (setq lo 0) - (setq hi (1+ hi)))))))) - (list hi lo us ps))) - -;;;###autoload -(defun time-less-p (t1 t2) - "Return non-nil if time value T1 is earlier than time value T2." - (with-decoded-time-value ((high1 low1 micro1 pico1 type1 t1) - (high2 low2 micro2 pico2 type2 t2)) - (or (< high1 high2) - (and (= high1 high2) - (or (< low1 low2) - (and (= low1 low2) - (or (< micro1 micro2) - (and (= micro1 micro2) - (< pico1 pico2))))))))) + "Convert SECONDS to a time value." + (time-add 0 seconds)) ;;;###autoload (defun days-to-time (days) "Convert DAYS into a time value." - (let* ((seconds (* 1.0 days 60 60 24)) - (high (condition-case nil (floor (/ seconds 65536)) - (range-error most-positive-fixnum)))) - (list high (condition-case nil (floor (- seconds (* 1.0 high 65536))) - (range-error 65535))))) + (let ((time (condition-case nil (seconds-to-time (* 86400.0 days)) + (range-error (list most-positive-fixnum 65535))))) + (if (integerp days) + (setcdr (cdr time) nil)) + time)) ;;;###autoload (defun time-since (time) @@ -207,53 +181,71 @@ TIME should be either a time value or a date-time string." (when (stringp time) ;; Convert date strings to internal time. (setq time (date-to-time time))) - (time-subtract (current-time) time)) + (time-subtract nil time)) ;;;###autoload (defalias 'subtract-time 'time-subtract) -;;;###autoload -(defun time-subtract (t1 t2) - "Subtract two time values, T1 minus T2. -Return the difference in the format of a time value." - (with-decoded-time-value ((high low micro pico type t1) - (high2 low2 micro2 pico2 type2 t2)) - (setq high (- high high2) - low (- low low2) - micro (- micro micro2) - pico (- pico pico2) - type (max type type2)) - (when (< pico 0) - (setq micro (1- micro) - pico (+ pico 1000000))) - (when (< micro 0) - (setq low (1- low) - micro (+ micro 1000000))) - (when (< low 0) - (setq high (1- high) - low (+ low 65536))) - (encode-time-value high low micro pico type))) +;; These autoloads do nothing in Emacs 25, where the functions are builtin. +;;;###autoload(autoload 'time-add "time-date") +;;;###autoload(autoload 'time-subtract "time-date") +;;;###autoload(autoload 'time-less-p "time-date") -;;;###autoload -(defun time-add (t1 t2) - "Add two time values T1 and T2. One should represent a time difference." - (with-decoded-time-value ((high low micro pico type t1) - (high2 low2 micro2 pico2 type2 t2)) - (setq high (+ high high2) - low (+ low low2) - micro (+ micro micro2) - pico (+ pico pico2) - type (max type type2)) - (when (>= pico 1000000) - (setq micro (1+ micro) - pico (- pico 1000000))) - (when (>= micro 1000000) - (setq low (1+ low) - micro (- micro 1000000))) - (when (>= low 65536) - (setq high (1+ high) - low (- low 65536))) - (encode-time-value high low micro pico type))) +(eval-when-compile + (when (not (featurep 'emacs)) + + (defun time-add (t1 t2) + "Add two time values T1 and T2. One should represent a time difference." + (with-decoded-time-value ((high low micro pico type t1) + (high2 low2 micro2 pico2 type2 t2)) + (setq high (+ high high2) + low (+ low low2) + micro (+ micro micro2) + pico (+ pico pico2) + type (max type type2)) + (when (>= pico 1000000) + (setq micro (1+ micro) + pico (- pico 1000000))) + (when (>= micro 1000000) + (setq low (1+ low) + micro (- micro 1000000))) + (when (>= low 65536) + (setq high (1+ high) + low (- low 65536))) + (encode-time-value high low micro pico type))) + + (defun time-subtract (t1 t2) + "Subtract two time values, T1 minus T2. +Return the difference in the format of a time value." + (with-decoded-time-value ((high low micro pico type t1) + (high2 low2 micro2 pico2 type2 t2)) + (setq high (- high high2) + low (- low low2) + micro (- micro micro2) + pico (- pico pico2) + type (max type type2)) + (when (< pico 0) + (setq micro (1- micro) + pico (+ pico 1000000))) + (when (< micro 0) + (setq low (1- low) + micro (+ micro 1000000))) + (when (< low 0) + (setq high (1- high) + low (+ low 65536))) + (encode-time-value high low micro pico type))) + + (defun time-less-p (t1 t2) + "Return non-nil if time value T1 is earlier than time value T2." + (with-decoded-time-value ((high1 low1 micro1 pico1 type1 t1) + (high2 low2 micro2 pico2 type2 t2)) + (or (< high1 high2) + (and (= high1 high2) + (or (< low1 low2) + (and (= low1 low2) + (or (< micro1 micro2) + (and (= micro1 micro2) + (< pico1 pico2))))))))))) ;;;###autoload (defun date-to-day (date) |