diff options
| author | Paul Eggert | 2014-11-16 20:38:15 -0800 |
|---|---|---|
| committer | Paul Eggert | 2014-11-16 20:41:22 -0800 |
| commit | 0921dbc3ab4dcc6b291ef45e46a24b322bbcb885 (patch) | |
| tree | 0e320978c7d30af415bb7de6e0b8f6735a3ca3d1 /lisp/calendar | |
| parent | 058f56d24f776bdc25bcac86fe1f8969a78374e9 (diff) | |
| download | emacs-0921dbc3ab4dcc6b291ef45e46a24b322bbcb885.tar.gz emacs-0921dbc3ab4dcc6b291ef45e46a24b322bbcb885.zip | |
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." | |||
| 179 | (if (eq (car (current-time-zone probe)) hi-utc-diff) | 179 | (if (eq (car (current-time-zone probe)) hi-utc-diff) |
| 180 | (setq hi probe) | 180 | (setq hi probe) |
| 181 | (setq lo probe))) | 181 | (setq lo probe))) |
| 182 | (setcdr hi (list (cdr hi))) | ||
| 182 | hi)))) | 183 | hi)))) |
| 183 | 184 | ||
| 184 | (autoload 'calendar-persian-to-absolute "cal-persia") | 185 | (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 @@ | |||
| 30 | ;; value equal to HIGH * 2^16 + LOW + USEC * 10^-6 + PSEC * 10^-12 | 30 | ;; value equal to HIGH * 2^16 + LOW + USEC * 10^-6 + PSEC * 10^-12 |
| 31 | ;; seconds, where missing components are treated as zero. HIGH can be | 31 | ;; seconds, where missing components are treated as zero. HIGH can be |
| 32 | ;; negative, either because the value is a time difference, or because | 32 | ;; negative, either because the value is a time difference, or because |
| 33 | ;; the machine supports negative time stamps that fall before the epoch. | 33 | ;; it represents a time stamp before the epoch. Typically, there are |
| 34 | ;; The macro `with-decoded-time-value' and the function | 34 | ;; more time values than the underlying system time type supports, |
| 35 | ;; `encode-time-value' make it easier to deal with these formats. | 35 | ;; but the reverse can also be true. |
| 36 | ;; See `time-subtract' for an example of how to use them. | ||
| 37 | 36 | ||
| 38 | ;;; Code: | 37 | ;;; Code: |
| 39 | 38 | ||
| @@ -71,6 +70,7 @@ list (HIGH LOW MICRO PICO)." | |||
| 71 | ,low ,micro) | 70 | ,low ,micro) |
| 72 | (when pico `(,pico)) | 71 | (when pico `(,pico)) |
| 73 | (when type `(,type))) | 72 | (when type `(,type))) |
| 73 | (or ,gensym (setq ,gensym (current-time))) | ||
| 74 | (if (consp ,gensym) | 74 | (if (consp ,gensym) |
| 75 | (progn | 75 | (progn |
| 76 | (setq ,low (pop ,gensym)) | 76 | (setq ,low (pop ,gensym)) |
| @@ -108,6 +108,10 @@ it is assumed that PICO was omitted and should be treated as zero." | |||
| 108 | ((eq type 3) (list high low micro pico)) | 108 | ((eq type 3) (list high low micro pico)) |
| 109 | ((null type) (encode-time-value high low micro 0 pico)))) | 109 | ((null type) (encode-time-value high low micro 0 pico)))) |
| 110 | 110 | ||
| 111 | (when (featurep 'emacs) | ||
| 112 | (make-obsolete 'encode-time-value nil "25.1") | ||
| 113 | (make-obsolete 'with-decoded-time-value nil "25.1")) | ||
| 114 | |||
| 111 | (autoload 'parse-time-string "parse-time") | 115 | (autoload 'parse-time-string "parse-time") |
| 112 | (autoload 'timezone-make-date-arpa-standard "timezone") | 116 | (autoload 'timezone-make-date-arpa-standard "timezone") |
| 113 | 117 | ||
| @@ -158,47 +162,17 @@ TIME defaults to the current time." | |||
| 158 | 162 | ||
| 159 | ;;;###autoload | 163 | ;;;###autoload |
| 160 | (defun seconds-to-time (seconds) | 164 | (defun seconds-to-time (seconds) |
| 161 | "Convert SECONDS (a floating point number) to a time value." | 165 | "Convert SECONDS to a time value." |
| 162 | (let* ((usec (* 1000000 (mod seconds 1))) | 166 | (time-add 0 seconds)) |
| 163 | (ps (round (* 1000000 (mod usec 1)))) | ||
| 164 | (us (floor usec)) | ||
| 165 | (lo (floor (mod seconds 65536))) | ||
| 166 | (hi (floor seconds 65536))) | ||
| 167 | (if (eq ps 1000000) | ||
| 168 | (progn | ||
| 169 | (setq ps 0) | ||
| 170 | (setq us (1+ us)) | ||
| 171 | (if (eq us 1000000) | ||
| 172 | (progn | ||
| 173 | (setq us 0) | ||
| 174 | (setq lo (1+ lo)) | ||
| 175 | (if (eq lo 65536) | ||
| 176 | (progn | ||
| 177 | (setq lo 0) | ||
| 178 | (setq hi (1+ hi)))))))) | ||
| 179 | (list hi lo us ps))) | ||
| 180 | |||
| 181 | ;;;###autoload | ||
| 182 | (defun time-less-p (t1 t2) | ||
| 183 | "Return non-nil if time value T1 is earlier than time value T2." | ||
| 184 | (with-decoded-time-value ((high1 low1 micro1 pico1 type1 t1) | ||
| 185 | (high2 low2 micro2 pico2 type2 t2)) | ||
| 186 | (or (< high1 high2) | ||
| 187 | (and (= high1 high2) | ||
| 188 | (or (< low1 low2) | ||
| 189 | (and (= low1 low2) | ||
| 190 | (or (< micro1 micro2) | ||
| 191 | (and (= micro1 micro2) | ||
| 192 | (< pico1 pico2))))))))) | ||
| 193 | 167 | ||
| 194 | ;;;###autoload | 168 | ;;;###autoload |
| 195 | (defun days-to-time (days) | 169 | (defun days-to-time (days) |
| 196 | "Convert DAYS into a time value." | 170 | "Convert DAYS into a time value." |
| 197 | (let* ((seconds (* 1.0 days 60 60 24)) | 171 | (let ((time (condition-case nil (seconds-to-time (* 86400.0 days)) |
| 198 | (high (condition-case nil (floor (/ seconds 65536)) | 172 | (range-error (list most-positive-fixnum 65535))))) |
| 199 | (range-error most-positive-fixnum)))) | 173 | (if (integerp days) |
| 200 | (list high (condition-case nil (floor (- seconds (* 1.0 high 65536))) | 174 | (setcdr (cdr time) nil)) |
| 201 | (range-error 65535))))) | 175 | time)) |
| 202 | 176 | ||
| 203 | ;;;###autoload | 177 | ;;;###autoload |
| 204 | (defun time-since (time) | 178 | (defun time-since (time) |
| @@ -207,53 +181,71 @@ TIME should be either a time value or a date-time string." | |||
| 207 | (when (stringp time) | 181 | (when (stringp time) |
| 208 | ;; Convert date strings to internal time. | 182 | ;; Convert date strings to internal time. |
| 209 | (setq time (date-to-time time))) | 183 | (setq time (date-to-time time))) |
| 210 | (time-subtract (current-time) time)) | 184 | (time-subtract nil time)) |
| 211 | 185 | ||
| 212 | ;;;###autoload | 186 | ;;;###autoload |
| 213 | (defalias 'subtract-time 'time-subtract) | 187 | (defalias 'subtract-time 'time-subtract) |
| 214 | 188 | ||
| 215 | ;;;###autoload | 189 | ;; These autoloads do nothing in Emacs 25, where the functions are builtin. |
| 216 | (defun time-subtract (t1 t2) | 190 | ;;;###autoload(autoload 'time-add "time-date") |
| 217 | "Subtract two time values, T1 minus T2. | 191 | ;;;###autoload(autoload 'time-subtract "time-date") |
| 218 | Return the difference in the format of a time value." | 192 | ;;;###autoload(autoload 'time-less-p "time-date") |
| 219 | (with-decoded-time-value ((high low micro pico type t1) | ||
| 220 | (high2 low2 micro2 pico2 type2 t2)) | ||
| 221 | (setq high (- high high2) | ||
| 222 | low (- low low2) | ||
| 223 | micro (- micro micro2) | ||
| 224 | pico (- pico pico2) | ||
| 225 | type (max type type2)) | ||
| 226 | (when (< pico 0) | ||
| 227 | (setq micro (1- micro) | ||
| 228 | pico (+ pico 1000000))) | ||
| 229 | (when (< micro 0) | ||
| 230 | (setq low (1- low) | ||
| 231 | micro (+ micro 1000000))) | ||
| 232 | (when (< low 0) | ||
| 233 | (setq high (1- high) | ||
| 234 | low (+ low 65536))) | ||
| 235 | (encode-time-value high low micro pico type))) | ||
| 236 | 193 | ||
| 237 | ;;;###autoload | 194 | (eval-when-compile |
| 238 | (defun time-add (t1 t2) | 195 | (when (not (featurep 'emacs)) |
| 239 | "Add two time values T1 and T2. One should represent a time difference." | 196 | |
| 240 | (with-decoded-time-value ((high low micro pico type t1) | 197 | (defun time-add (t1 t2) |
| 241 | (high2 low2 micro2 pico2 type2 t2)) | 198 | "Add two time values T1 and T2. One should represent a time difference." |
| 242 | (setq high (+ high high2) | 199 | (with-decoded-time-value ((high low micro pico type t1) |
| 243 | low (+ low low2) | 200 | (high2 low2 micro2 pico2 type2 t2)) |
| 244 | micro (+ micro micro2) | 201 | (setq high (+ high high2) |
| 245 | pico (+ pico pico2) | 202 | low (+ low low2) |
| 246 | type (max type type2)) | 203 | micro (+ micro micro2) |
| 247 | (when (>= pico 1000000) | 204 | pico (+ pico pico2) |
| 248 | (setq micro (1+ micro) | 205 | type (max type type2)) |
| 249 | pico (- pico 1000000))) | 206 | (when (>= pico 1000000) |
| 250 | (when (>= micro 1000000) | 207 | (setq micro (1+ micro) |
| 251 | (setq low (1+ low) | 208 | pico (- pico 1000000))) |
| 252 | micro (- micro 1000000))) | 209 | (when (>= micro 1000000) |
| 253 | (when (>= low 65536) | 210 | (setq low (1+ low) |
| 254 | (setq high (1+ high) | 211 | micro (- micro 1000000))) |
| 255 | low (- low 65536))) | 212 | (when (>= low 65536) |
| 256 | (encode-time-value high low micro pico type))) | 213 | (setq high (1+ high) |
| 214 | low (- low 65536))) | ||
| 215 | (encode-time-value high low micro pico type))) | ||
| 216 | |||
| 217 | (defun time-subtract (t1 t2) | ||
| 218 | "Subtract two time values, T1 minus T2. | ||
| 219 | Return the difference in the format of a time value." | ||
| 220 | (with-decoded-time-value ((high low micro pico type t1) | ||
| 221 | (high2 low2 micro2 pico2 type2 t2)) | ||
| 222 | (setq high (- high high2) | ||
| 223 | low (- low low2) | ||
| 224 | micro (- micro micro2) | ||
| 225 | pico (- pico pico2) | ||
| 226 | type (max type type2)) | ||
| 227 | (when (< pico 0) | ||
| 228 | (setq micro (1- micro) | ||
| 229 | pico (+ pico 1000000))) | ||
| 230 | (when (< micro 0) | ||
| 231 | (setq low (1- low) | ||
| 232 | micro (+ micro 1000000))) | ||
| 233 | (when (< low 0) | ||
| 234 | (setq high (1- high) | ||
| 235 | low (+ low 65536))) | ||
| 236 | (encode-time-value high low micro pico type))) | ||
| 237 | |||
| 238 | (defun time-less-p (t1 t2) | ||
| 239 | "Return non-nil if time value T1 is earlier than time value T2." | ||
| 240 | (with-decoded-time-value ((high1 low1 micro1 pico1 type1 t1) | ||
| 241 | (high2 low2 micro2 pico2 type2 t2)) | ||
| 242 | (or (< high1 high2) | ||
| 243 | (and (= high1 high2) | ||
| 244 | (or (< low1 low2) | ||
| 245 | (and (= low1 low2) | ||
| 246 | (or (< micro1 micro2) | ||
| 247 | (and (= micro1 micro2) | ||
| 248 | (< pico1 pico2))))))))))) | ||
| 257 | 249 | ||
| 258 | ;;;###autoload | 250 | ;;;###autoload |
| 259 | (defun date-to-day (date) | 251 | (defun date-to-day (date) |