comparison lisp/calendar/cal-dst.el @ 93526:90118d6d9050

(calendar-time-zone-daylight-rules): Simplify.
author Glenn Morris <rgm@gnu.org>
date Wed, 02 Apr 2008 03:18:55 +0000
parents 7aed3058864c
children e13ec6b5b482
comparison
equal deleted inserted replaced
93525:26506821c407 93526:90118d6d9050
191 (weekday (% abs-date 7)) 191 (weekday (% abs-date 7))
192 (m (extract-calendar-month date)) 192 (m (extract-calendar-month date))
193 (d (extract-calendar-day date)) 193 (d (extract-calendar-day date))
194 (y (extract-calendar-year date)) 194 (y (extract-calendar-year date))
195 (last (calendar-last-day-of-month m y)) 195 (last (calendar-last-day-of-month m y))
196 (candidate-rules 196 j rlist
197 (candidate-rules ; these return Gregorian dates
197 (append 198 (append
198 ;; Day D of month M. 199 ;; Day D of month M.
199 (list (list 'list m d 'year)) 200 `((list ,m ,d year))
200 ;; The first WEEKDAY of month M. 201 ;; The first WEEKDAY of month M.
201 (if (< d 8) 202 (if (< d 8)
202 (list (list 'calendar-nth-named-day 1 weekday m 'year))) 203 `((calendar-nth-named-day 1 ,weekday ,m year)))
203 ;; The last WEEKDAY of month M. 204 ;; The last WEEKDAY of month M.
204 (if (> d (- last 7)) 205 (if (> d (- last 7))
205 (list (list 'calendar-nth-named-day -1 weekday m 'year))) 206 `((calendar-nth-named-day -1 ,weekday ,m year)))
206 ;; The first WEEKDAY after day J of month M, for D-6 < J <= D. 207 (progn
207 (let (l) 208 ;; The first WEEKDAY after day J of month M, for D-6 < J <= D.
208 (calendar-for-loop j from (max 2 (- d 6)) to (min d (- last 8)) do 209 (setq j (1- (max 2 (- d 6))))
209 (setq l 210 (while (<= (setq j (1+ j)) (min d (- last 8)))
210 (cons 211 (push `(calendar-nth-named-day 1 ,weekday ,m year ,j) rlist))
211 (list 'calendar-nth-named-day 212 rlist)
212 1 weekday m 'year j)
213 l)))
214 l)
215 ;; 01-01 and 07-01 for this year's Persian calendar. 213 ;; 01-01 and 07-01 for this year's Persian calendar.
214 ;; FIXME what does the Persian calendar have to do with this?
216 (if (and (= m 3) (<= 20 d) (<= d 21)) 215 (if (and (= m 3) (<= 20 d) (<= d 21))
217 '((calendar-gregorian-from-absolute 216 '((calendar-gregorian-from-absolute
218 (calendar-absolute-from-persian 217 (calendar-absolute-from-persian `(1 1 ,(- year 621))))))
219 (list 1 1 (- year 621))))))
220 (if (and (= m 9) (<= 22 d) (<= d 23)) 218 (if (and (= m 9) (<= 22 d) (<= d 23))
221 '((calendar-gregorian-from-absolute 219 '((calendar-gregorian-from-absolute
222 (calendar-absolute-from-persian 220 (calendar-absolute-from-persian `(7 1 ,(- year 621))))))))
223 (list 7 1 (- year 621))))))))
224 (prevday-sec (- -1 utc-diff)) ; last sec of previous local day 221 (prevday-sec (- -1 utc-diff)) ; last sec of previous local day
225 (year (1+ y))) 222 (year (1+ y))
223 new-rules)
226 ;; Scan through the next few years until only one rule remains. 224 ;; Scan through the next few years until only one rule remains.
227 (while (let ((rules candidate-rules) 225 (while (cdr candidate-rules)
228 new-rules) 226 (dolist (rule candidate-rules)
229 (dolist (rule rules) 227 ;; The rule we return should give a Gregorian date, but here
230 (let ((date 228 ;; we require an absolute date. The following is for efficiency.
231 ;; The following is much faster than 229 (setq date (cond ((eq (car rule) 'calendar-nth-named-day)
232 ;; (calendar-absolute-from-gregorian (eval rule)). 230 (eval (cons 'calendar-nth-named-absday (cdr rule))))
233 (cond ((eq (car rule) 'calendar-nth-named-day) 231 ((eq (car rule) 'calendar-gregorian-from-absolute)
234 (eval (cons 'calendar-nth-named-absday 232 (eval (cdr rule)))
235 (cdr rule)))) 233 (t (calendar-absolute-from-gregorian (eval rule)))))
236 ((eq (car rule) 'calendar-gregorian-from-absolute) 234 (or (equal (current-time-zone
237 (eval (cadr rule))) 235 (calendar-time-from-absolute date prevday-sec))
238 (t (calendar-absolute-from-gregorian 236 (current-time-zone
239 (eval rule)))))) 237 (calendar-time-from-absolute (1+ date) prevday-sec)))
240 (or (equal 238 (setq new-rules (cons rule new-rules))))
241 (current-time-zone 239 ;; If no rules remain, just use the first candidate rule;
242 (calendar-time-from-absolute date prevday-sec)) 240 ;; it's wrong in general, but it's right for at least one year.
243 (current-time-zone 241 (setq candidate-rules (if new-rules (nreverse new-rules)
244 (calendar-time-from-absolute (1+ date) prevday-sec))) 242 (list (car candidate-rules)))
245 (setq new-rules (cons rule new-rules))))) 243 year (1+ year)))
246 ;; If no rules remain, just use the first candidate rule;
247 ;; it's wrong in general, but it's right for at least one year.
248 (setq candidate-rules (if new-rules (nreverse new-rules)
249 (list (car candidate-rules)))
250 year (1+ year))
251 (cdr candidate-rules)))
252 (car candidate-rules))) 244 (car candidate-rules)))
253 245
254 ;; TODO it might be better to extract this information directly from 246 ;; TODO it might be better to extract this information directly from
255 ;; the system timezone database. But cross-platform...? 247 ;; the system timezone database. But cross-platform...?
256 ;; See thread 248 ;; See thread