aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLute Kamstra2005-03-23 10:09:18 +0000
committerLute Kamstra2005-03-23 10:09:18 +0000
commitca2d9ad84391dcb97ce9b9514a7b3377be3d68c2 (patch)
tree9c5b6a34514a7320af272b753efcdf21a62ea8d4
parent8725c7925ef1ce95efb1f50d48d17f437e9c46a4 (diff)
downloademacs-ca2d9ad84391dcb97ce9b9514a7b3377be3d68c2.tar.gz
emacs-ca2d9ad84391dcb97ce9b9514a7b3377be3d68c2.zip
Add comment on time value formats. Don't require parse-time.
(with-decoded-time-value): New macro. (encode-time-value): New function. (time-to-seconds, time-less-p, time-subtract, time-add): Use them. (days-to-time): Return a valid time value when arg is huge. (time-since): Use time-subtract. (time-to-number-of-days): Use time-to-seconds.
-rw-r--r--lisp/ChangeLog11
-rw-r--r--lisp/calendar/time-date.el157
2 files changed, 120 insertions, 48 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4e2472e70f9..b199bf9e3bf 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,14 @@
12005-03-23 Lute Kamstra <lute@gnu.org>
2
3 * calendar/time-date.el: Add comment on time value formats. Don't
4 require parse-time.
5 (with-decoded-time-value): New macro.
6 (encode-time-value): New function.
7 (time-to-seconds, time-less-p, time-subtract, time-add): Use them.
8 (days-to-time): Return a valid time value when arg is huge.
9 (time-since): Use time-subtract.
10 (time-to-number-of-days): Use time-to-seconds.
11
12005-03-23 David Ponce <david@dponce.com> 122005-03-23 David Ponce <david@dponce.com>
2 13
3 * recentf.el: (recentf-keep): New option. 14 * recentf.el: (recentf-keep): New option.
diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index 3a850717298..a4acb8b9291 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -1,5 +1,5 @@
1;;; time-date.el --- date and time handling functions 1;;; time-date.el --- date and time handling functions
2;; Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc. 2;; Copyright (C) 1998, 1999, 2000, 2004, 2005 Free Software Foundation, Inc.
3 3
4;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 4;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
5;; Masanobu Umeda <umerin@mse.kyutech.ac.jp> 5;; Masanobu Umeda <umerin@mse.kyutech.ac.jp>
@@ -24,9 +24,71 @@
24 24
25;;; Commentary: 25;;; Commentary:
26 26
27;; Time values come in three formats. The oldest format is a cons
28;; cell of the form (HIGH . LOW). This format is obsolete, but still
29;; supported. The two other formats are the lists (HIGH LOW) and
30;; (HIGH LOW MICRO). The first two formats specify HIGH * 2^16 + LOW
31;; seconds; the third format specifies HIGH * 2^16 + LOW + MICRO /
32;; 1000000 seconds. We should have 0 <= MICRO < 1000000 and 0 <= LOW
33;; < 2^16. If the time value represents a point in time, then HIGH is
34;; nonnegative. If the time value is a time difference, then HIGH can
35;; be negative as well. The macro `with-decoded-time-value' and the
36;; function `encode-time-value' make it easier to deal with these
37;; three formats. See `time-subtract' for an example of how to use
38;; them.
39
27;;; Code: 40;;; Code:
28 41
29(require 'parse-time) 42(defmacro with-decoded-time-value (varlist &rest body)
43 "Decode a time value and bind it according to VARLIST, then eval BODY.
44
45The value of the last form in BODY is returned.
46
47Each element of the list VARLIST is a list of the form
48\(HIGH-SYMBOL LOW-SYMBOL MICRO-SYMBOL [TYPE-SYMBOL] TIME-VALUE).
49The time value TIME-VALUE is decoded and the result it bound to
50the symbols HIGH-SYMBOL, LOW-SYMBOL and MICRO-SYMBOL.
51
52The optional TYPE-SYMBOL is bound to the type of the time value.
53Type 0 is the cons cell (HIGH . LOW), type 1 is the list (HIGH
54LOW), and type 3 is the list (HIGH LOW MICRO)."
55 (declare (indent 1)
56 (debug ((&rest (symbolp symbolp symbolp &or [symbolp form] form))
57 body)))
58 (if varlist
59 (let* ((elt (pop varlist))
60 (high (pop elt))
61 (low (pop elt))
62 (micro (pop elt))
63 (type (unless (eq (length elt) 1)
64 (pop elt)))
65 (time-value (car elt))
66 (gensym (make-symbol "time")))
67 `(let* ,(append `((,gensym ,time-value)
68 (,high (pop ,gensym))
69 ,low ,micro)
70 (when type `(,type)))
71 (if (consp ,gensym)
72 (progn
73 (setq ,low (pop ,gensym))
74 (if ,gensym
75 ,(append `(setq ,micro (car ,gensym))
76 (when type `(,type 2)))
77 ,(append `(setq ,micro 0)
78 (when type `(,type 1)))))
79 ,(append `(setq ,low ,gensym ,micro 0)
80 (when type `(,type 0))))
81 (with-decoded-time-value ,varlist ,@body)))
82 `(progn ,@body)))
83
84(defun encode-time-value (high low micro type)
85 "Encode HIGH, LOW, and MICRO into a time value of type TYPE.
86Type 0 is the cons cell (HIGH . LOW), type 1 is the list (HIGH LOW),
87and type 3 is the list (HIGH LOW MICRO)."
88 (cond
89 ((eq type 0) (cons high low))
90 ((eq type 1) (list high low))
91 ((eq type 2) (list high low micro))))
30 92
31(autoload 'timezone-make-date-arpa-standard "timezone") 93(autoload 'timezone-make-date-arpa-standard "timezone")
32 94
@@ -49,33 +111,37 @@
49(defun time-to-seconds (time) 111(defun time-to-seconds (time)
50 "Convert time value TIME to a floating point number. 112 "Convert time value TIME to a floating point number.
51You can use `float-time' instead." 113You can use `float-time' instead."
52 (+ (* (car time) 65536.0) 114 (with-decoded-time-value ((high low micro time))
53 (cadr time) 115 (+ (* 1.0 high #x10000)
54 (/ (or (nth 2 time) 0) 1000000.0))) 116 low
117 (/ micro 1000000.0))))
55 118
56;;;###autoload 119;;;###autoload
57(defun seconds-to-time (seconds) 120(defun seconds-to-time (seconds)
58 "Convert SECONDS (a floating point number) to a time value." 121 "Convert SECONDS (a floating point number) to a time value."
59 (list (floor seconds 65536) 122 (list (floor seconds #x10000)
60 (floor (mod seconds 65536)) 123 (floor (mod seconds #x10000))
61 (floor (* (- seconds (ffloor seconds)) 1000000)))) 124 (floor (* (- seconds (ffloor seconds)) 1000000))))
62 125
63;;;###autoload 126;;;###autoload
64(defun time-less-p (t1 t2) 127(defun time-less-p (t1 t2)
65 "Say whether time value T1 is less than time value T2." 128 "Say whether time value T1 is less than time value T2."
66 (or (< (car t1) (car t2)) 129 (with-decoded-time-value ((high1 low1 micro1 t1)
67 (and (= (car t1) (car t2)) 130 (high2 low2 micro2 t2))
68 (< (nth 1 t1) (nth 1 t2))))) 131 (or (< high1 high2)
132 (and (= high1 high2)
133 (or (< low1 low2)
134 (and (= low1 low2)
135 (< micro1 micro2)))))))
69 136
70;;;###autoload 137;;;###autoload
71(defun days-to-time (days) 138(defun days-to-time (days)
72 "Convert DAYS into a time value." 139 "Convert DAYS into a time value."
73 (let* ((seconds (* 1.0 days 60 60 24)) 140 (let* ((seconds (* 1.0 days 60 60 24))
74 (rest (expt 2 16)) 141 (high (condition-case nil (floor (/ seconds #x10000))
75 (ms (condition-case nil (floor (/ seconds rest)) 142 (range-error most-positive-fixnum))))
76 (range-error (expt 2 16))))) 143 (list high (condition-case nil (floor (- seconds (* 1.0 high #x10000)))
77 (list ms (condition-case nil (round (- seconds (* ms rest))) 144 (range-error #xffff)))))
78 (range-error (expt 2 16))))))
79 145
80;;;###autoload 146;;;###autoload
81(defun time-since (time) 147(defun time-since (time)
@@ -84,11 +150,7 @@ TIME should be either a time value or a date-time string."
84 (when (stringp time) 150 (when (stringp time)
85 ;; Convert date strings to internal time. 151 ;; Convert date strings to internal time.
86 (setq time (date-to-time time))) 152 (setq time (date-to-time time)))
87 (let* ((current (current-time)) 153 (time-subtract (current-time) time))
88 (rest (when (< (nth 1 current) (nth 1 time))
89 (expt 2 16))))
90 (list (- (+ (car current) (if rest -1 0)) (car time))
91 (- (+ (or rest 0) (nth 1 current)) (nth 1 time)))))
92 154
93;;;###autoload 155;;;###autoload
94(defalias 'subtract-time 'time-subtract) 156(defalias 'subtract-time 'time-subtract)
@@ -97,37 +159,36 @@ TIME should be either a time value or a date-time string."
97(defun time-subtract (t1 t2) 159(defun time-subtract (t1 t2)
98 "Subtract two time values. 160 "Subtract two time values.
99Return the difference in the format of a time value." 161Return the difference in the format of a time value."
100 (let ((borrow (< (cadr t1) (cadr t2)))) 162 (with-decoded-time-value ((high low micro type t1)
101 (list (- (car t1) (car t2) (if borrow 1 0)) 163 (high2 low2 micro2 type2 t2))
102 (- (+ (if borrow 65536 0) (cadr t1)) (cadr t2))))) 164 (setq high (- high high2)
165 low (- low low2)
166 micro (- micro micro2)
167 type (max type type2))
168 (when (< micro 0)
169 (setq low (1- low)
170 micro (+ micro 1000000)))
171 (when (< low 0)
172 (setq high (1- high)
173 low (+ low #x10000)))
174 (encode-time-value high low micro type)))
103 175
104;;;###autoload 176;;;###autoload
105(defun time-add (t1 t2) 177(defun time-add (t1 t2)
106 "Add two time values. One should represent a time difference." 178 "Add two time values. One should represent a time difference."
107 (let ((high (car t1)) 179 (with-decoded-time-value ((high low micro type t1)
108 (low (if (consp (cdr t1)) (nth 1 t1) (cdr t1))) 180 (high2 low2 micro2 type2 t2))
109 (micro (if (numberp (car-safe (cdr-safe (cdr t1)))) 181 (setq high (+ high high2)
110 (nth 2 t1) 182 low (+ low low2)
111 0)) 183 micro (+ micro micro2)
112 (high2 (car t2)) 184 type (max type type2))
113 (low2 (if (consp (cdr t2)) (nth 1 t2) (cdr t2))) 185 (when (>= micro 1000000)
114 (micro2 (if (numberp (car-safe (cdr-safe (cdr t2)))) 186 (setq low (1+ low)
115 (nth 2 t2) 187 micro (- micro 1000000)))
116 0))) 188 (when (>= low #x10000)
117 ;; Add 189 (setq high (1+ high)
118 (setq micro (+ micro micro2)) 190 low (- low #x10000)))
119 (setq low (+ low low2)) 191 (encode-time-value high low micro type)))
120 (setq high (+ high high2))
121
122 ;; Normalize
123 ;; `/' rounds towards zero while `mod' returns a positive number,
124 ;; so we can't rely on (= a (+ (* 100 (/ a 100)) (mod a 100))).
125 (setq low (+ low (/ micro 1000000) (if (< micro 0) -1 0)))
126 (setq micro (mod micro 1000000))
127 (setq high (+ high (/ low 65536) (if (< low 0) -1 0)))
128 (setq low (logand low 65535))
129
130 (list high low micro)))
131 192
132;;;###autoload 193;;;###autoload
133(defun date-to-day (date) 194(defun date-to-day (date)
@@ -180,7 +241,7 @@ The Gregorian date Sunday, December 31, 1bce is imaginary."
180(defun time-to-number-of-days (time) 241(defun time-to-number-of-days (time)
181 "Return the number of days represented by TIME. 242 "Return the number of days represented by TIME.
182The number of days will be returned as a floating point number." 243The number of days will be returned as a floating point number."
183 (/ (+ (* 1.0 65536 (car time)) (cadr time)) (* 60 60 24))) 244 (/ (time-to-seconds time) (* 60 60 24)))
184 245
185;;;###autoload 246;;;###autoload
186(defun safe-date-to-time (date) 247(defun safe-date-to-time (date)