aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/timezone.el
diff options
context:
space:
mode:
authorMark A. Hershberger2009-08-14 18:18:39 +0000
committerMark A. Hershberger2009-08-14 18:18:39 +0000
commitb6377f1dc339aef13b2982fbc987c8b584911a38 (patch)
treead9a720ccb77801caee38b5af37f9f49811eb7ad /lisp/timezone.el
parent4e021e652a2daf6cd3cec08aa893eb7449d4a61e (diff)
downloademacs-b6377f1dc339aef13b2982fbc987c8b584911a38.tar.gz
emacs-b6377f1dc339aef13b2982fbc987c8b584911a38.zip
add ability to understand ISO8601 basic format as well as the extended one.
Diffstat (limited to 'lisp/timezone.el')
-rw-r--r--lisp/timezone.el161
1 files changed, 84 insertions, 77 deletions
diff --git a/lisp/timezone.el b/lisp/timezone.el
index 31988b34d4c..e351a88609c 100644
--- a/lisp/timezone.el
+++ b/lisp/timezone.el
@@ -134,99 +134,106 @@ Understands the following styles:
134 (6) Thu, 11 Apr 16:17:12 91 [MET] 134 (6) Thu, 11 Apr 16:17:12 91 [MET]
135 (7) Mon, 6 Jul 16:47:20 T 1992 [MET] 135 (7) Mon, 6 Jul 16:47:20 T 1992 [MET]
136 (8) 1996-06-24 21:13:12 [GMT] 136 (8) 1996-06-24 21:13:12 [GMT]
137 (9) 1996-06-24 21:13-ZONE" 137 (9) 1996-06-24 21:13-ZONE
138 ;; Get rid of any text properties. 138 (10) 19960624T211312"
139 ;; Get rid of any text properties.
139 (and (stringp date) 140 (and (stringp date)
140 (or (text-properties-at 0 date) 141 (or (text-properties-at 0 date)
141 (next-property-change 0 date)) 142 (next-property-change 0 date))
142 (setq date (copy-sequence date)) 143 (setq date (copy-sequence date))
143 (set-text-properties 0 (length date) nil date)) 144 (set-text-properties 0 (length date) nil date))
144 (let ((date (or date "")) 145 (let ((date (or date ""))
145 (year nil) 146 (year nil)
146 (month nil) 147 (month nil)
147 (day nil) 148 (day nil)
148 (time nil) 149 (time nil)
149 (zone nil)) ;This may be nil. 150 (zone nil)) ;This may be nil.
150 (cond ((string-match 151 (cond ((string-match
151 "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)" date) 152 "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)" date)
152 ;; Styles: (1) and (2) with timezone and buggy timezone 153 ;; Styles: (1) and (2) with timezone and buggy timezone
153 ;; This is most common in mail and news, 154 ;; This is most common in mail and news,
154 ;; so it is worth trying first. 155 ;; so it is worth trying first.
155 (setq year 3 month 2 day 1 time 4 zone 5)) 156 (setq year 3 month 2 day 1 time 4 zone 5))
156 ((string-match 157 ((string-match
157 "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]*\\'" date) 158 "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]*\\'" date)
158 ;; Styles: (1) and (2) without timezone 159 ;; Styles: (1) and (2) without timezone
159 (setq year 3 month 2 day 1 time 4 zone nil)) 160 (setq year 3 month 2 day 1 time 4 zone nil))
160 ((string-match 161 ((string-match
161 "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\'" date) 162 "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\'" date)
162 ;; Styles: (6) and (7) without timezone 163 ;; Styles: (6) and (7) without timezone
163 (setq year 6 month 3 day 2 time 4 zone nil)) 164 (setq year 6 month 3 day 2 time 4 zone nil))
164 ((string-match 165 ((string-match
165 "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date) 166 "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
166 ;; Styles: (6) and (7) with timezone and buggy timezone 167 ;; Styles: (6) and (7) with timezone and buggy timezone
167 (setq year 6 month 3 day 2 time 4 zone 7)) 168 (setq year 6 month 3 day 2 time 4 zone 7))
168 ((string-match 169 ((string-match
169 "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([0-9]+\\)" date) 170 "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([0-9]+\\)" date)
170 ;; Styles: (3) without timezone 171 ;; Styles: (3) without timezone
171 (setq year 4 month 1 day 2 time 3 zone nil)) 172 (setq year 4 month 1 day 2 time 3 zone nil))
172 ((string-match 173 ((string-match
173 "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)[ \t]+\\([0-9]+\\)" date) 174 "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)[ \t]+\\([0-9]+\\)" date)
174 ;; Styles: (3) with timezone 175 ;; Styles: (3) with timezone
175 (setq year 5 month 1 day 2 time 3 zone 4)) 176 (setq year 5 month 1 day 2 time 3 zone 4))
176 ((string-match 177 ((string-match
177 "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date) 178 "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
178 ;; Styles: (4) with timezone 179 ;; Styles: (4) with timezone
179 (setq year 3 month 2 day 1 time 4 zone 5)) 180 (setq year 3 month 2 day 1 time 4 zone 5))
180 ((string-match 181 ((string-match
181 "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\(\\.[0-9]+\\)?[ \t]+\\([-+a-zA-Z0-9]+\\)" date) 182 "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\(\\.[0-9]+\\)?[ \t]+\\([-+a-zA-Z0-9]+\\)" date)
182 ;; Styles: (5) with timezone. 183 ;; Styles: (5) with timezone.
183 (setq year 3 month 2 day 1 time 4 zone 6)) 184 (setq year 3 month 2 day 1 time 4 zone 6))
184 ((string-match 185 ((string-match
185 "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\(\\.[0-9]+\\)?" date) 186 "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\(\\.[0-9]+\\)?" date)
186 ;; Styles: (5) without timezone. 187 ;; Styles: (5) without timezone.
187 (setq year 3 month 2 day 1 time 4 zone nil)) 188 (setq year 3 month 2 day 1 time 4 zone nil))
188 ((string-match 189 ((string-match
189 "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)" date) 190 "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)" date)
190 ;; Styles: (8) with timezone. 191 ;; Styles: (8) with timezone.
191 (setq year 1 month 2 day 3 time 4 zone 5)) 192 (setq year 1 month 2 day 3 time 4 zone 5))
192 ((string-match 193 ((string-match
193 "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)[T \t]+\\([0-9]+:[0-9]+\\)[ \t]+\\([-+a-zA-Z0-9:]+\\)" date) 194 "\\([0-9]\\{4\\}\\)-?\\([0-9]\\{0,2\\}\\)-?\\([0-9]\\{0,2\\}\\)[T \t]+\\([0-9]\\{0,2\\}:?[0-9]\\{0,2\\}:?[0-9]\\{0,2\\}\\)[ \t]*\\([-+a-zA-Z]+[0-9:]*\\)" date)
194 ;; Styles: (8) with timezone with a colon in it. 195 ;; Styles: (8) with timezone with a colon in it.
195 (setq year 1 month 2 day 3 time 4 zone 5)) 196 (setq year 1 month 2 day 3 time 4 zone 5))
196 ((string-match 197 ((string-match
197 "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)[T \t]+\\([0-9]+:[0-9]+:[0-9]+\\)" date) 198 "\\([0-9]\\{4\\}\\)-?\\([0-9]\\{0,2\\}\\)-?\\([0-9]\\{0,2\\}\\)[T \t]+\\([0-9]+:?[0-9]+:?[0-9]+\\)" date)
198 ;; Styles: (8) without timezone. 199 ;; Styles: (8) without timezone.
199 (setq year 1 month 2 day 3 time 4 zone nil)) 200 (setq year 1 month 2 day 3 time 4 zone nil))
200 ) 201 )
202
201 (when year 203 (when year
202 (setq year (match-string year date)) 204 (setq year (match-string year date))
203 ;; Guess ambiguous years. Assume years < 69 don't predate the 205 ;; Guess ambiguous years. Assume years < 69 don't predate the
204 ;; Unix Epoch, so are 2000+. Three-digit years are assumed to 206 ;; Unix Epoch, so are 2000+. Three-digit years are assumed to
205 ;; be relative to 1900. 207 ;; be relative to 1900.
206 (if (< (length year) 4) 208 (when (< (length year) 4)
207 (let ((y (string-to-number year))) 209 (let ((y (string-to-number year)))
208 (if (< y 69) 210 (when (< y 69)
209 (setq y (+ y 100))) 211 (setq y (+ y 100)))
210 (setq year (int-to-string (+ 1900 y))))) 212 (setq year (int-to-string (+ 1900 y)))))
211 (setq month 213 (setq month
212 (if (= (aref date (+ (match-beginning month) 2)) ?-) 214 (if (or (= (aref date (+ (match-beginning month) 2)) ?-)
213 ;; Handle numeric months, spanning exactly two digits. 215 (let ((n (string-to-number
214 (substring date 216 (char-to-string
215 (match-beginning month) 217 (aref date (+ (match-beginning month) 2))))))
216 (+ (match-beginning month) 2)) 218 (= (aref (number-to-string n) 0)
217 (let* ((string (substring date 219 (aref date (+ (match-beginning month) 2)))))
218 (match-beginning month) 220 ;; Handle numeric months, spanning exactly two digits.
219 (+ (match-beginning month) 3))) 221 (substring date
220 (monthnum 222 (match-beginning month)
221 (cdr (assoc (upcase string) timezone-months-assoc)))) 223 (+ (match-beginning month) 2))
222 (if monthnum 224 (let* ((string (substring date
223 (int-to-string monthnum))))) 225 (match-beginning month)
226 (+ (match-beginning month) 3)))
227 (monthnum
228 (cdr (assoc (upcase string) timezone-months-assoc))))
229 (when monthnum
230 (int-to-string monthnum)))))
224 (setq day (match-string day date)) 231 (setq day (match-string day date))
225 (setq time (match-string time date))) 232 (setq time (match-string time date)))
226 (if zone (setq zone (match-string zone date))) 233 (when zone (setq zone (match-string zone date)))
227 ;; Return a vector. 234 ;; Return a vector.
228 (if (and year month) 235 (if (and year month)
229 (vector year month day time zone) 236 (vector year month day time zone)
230 (vector "0" "0" "0" "0" nil)))) 237 (vector "0" "0" "0" "0" nil))))
231 238
232(defun timezone-parse-time (time) 239(defun timezone-parse-time (time)