aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/calendar
diff options
context:
space:
mode:
authorPaul Eggert2014-11-16 20:38:15 -0800
committerPaul Eggert2014-11-16 20:41:22 -0800
commit0921dbc3ab4dcc6b291ef45e46a24b322bbcb885 (patch)
tree0e320978c7d30af415bb7de6e0b8f6735a3ca3d1 /lisp/calendar
parent058f56d24f776bdc25bcac86fe1f8969a78374e9 (diff)
downloademacs-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.el1
-rw-r--r--lisp/calendar/time-date.el158
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")
218Return 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.
219Return 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)