Update copyright year to 2014 by running admin/update-copyright.
[bpt/emacs.git] / lisp / calendar / cal-dst.el
CommitLineData
e716fd62 1;;; cal-dst.el --- calendar functions for daylight saving rules
3e03d7c7 2
ba318903 3;; Copyright (C) 1993-1996, 2001-2014 Free Software Foundation, Inc.
3e03d7c7
JB
4
5;; Author: Paul Eggert <eggert@twinsun.com>
71ea27ee 6;; Edward M. Reingold <reingold@cs.uiuc.edu>
dbfca9c4 7;; Maintainer: Glenn Morris <rgm@gnu.org>
3e03d7c7 8;; Keywords: calendar
e716fd62 9;; Human-Keywords: daylight saving time, calendar, diary, holidays
bd78fa1d 10;; Package: calendar
3e03d7c7
JB
11
12;; This file is part of GNU Emacs.
13
2ed66575 14;; GNU Emacs is free software: you can redistribute it and/or modify
59243403 15;; it under the terms of the GNU General Public License as published by
2ed66575
GM
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
59243403 18
3e03d7c7 19;; GNU Emacs is distributed in the hope that it will be useful,
59243403
RS
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
2ed66575 25;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
3e03d7c7
JB
26
27;;; Commentary:
28
b1c57079 29;; See calendar.el.
3e03d7c7 30
3e03d7c7
JB
31;;; Code:
32
33(require 'calendar)
34
ec1ee609
GM
35
36(defgroup calendar-dst nil
37 "Options related to Daylight Saving Time."
38 :prefix "calendar-"
39 :group 'calendar)
40
41
cd72c399
GM
42(defcustom calendar-dst-check-each-year-flag t
43 "Non-nil means to check each year for DST transitions as needed.
f3f4e600 44Otherwise assume the next two transitions found after the
cd72c399 45current date apply to all years. This is faster, but not always
e716fd62 46correct, since the dates of daylight saving transitions sometimes
cd72c399
GM
47change."
48 :type 'boolean
49 :version "22.1"
76db8823 50 :group 'calendar-dst)
cd72c399 51
ec1ee609
GM
52;;;###autoload
53(put 'calendar-daylight-savings-starts 'risky-local-variable t)
54(defcustom calendar-daylight-savings-starts '(calendar-dst-starts year)
55 "Sexp giving the date on which daylight saving time starts.
56This is an expression in the variable `year' whose value gives the Gregorian
57date in the form (month day year) on which daylight saving time starts. It is
58used to determine the starting date of daylight saving time for the holiday
59list and for correcting times of day in the solar and lunar calculations.
60
61For example, if daylight saving time is mandated to start on October 1,
62you would set `calendar-daylight-savings-starts' to
63
64 '(10 1 year)
65
66If it starts on the first Sunday in April, you would set it to
67
68 '(calendar-nth-named-day 1 0 4 year)
69
70If the locale never uses daylight saving time, set this to nil."
71 :type 'sexp
72 :group 'calendar-dst)
73
74;;;###autoload
75(put 'calendar-daylight-savings-ends 'risky-local-variable t)
76(defcustom calendar-daylight-savings-ends '(calendar-dst-ends year)
77 "Sexp giving the date on which daylight saving time ends.
78This is an expression in the variable `year' whose value gives the Gregorian
79date in the form (month day year) on which daylight saving time ends. It is
80used to determine the starting date of daylight saving time for the holiday
81list and for correcting times of day in the solar and lunar calculations.
82
83For example, if daylight saving time ends on the last Sunday in October:
84
85 '(calendar-nth-named-day -1 0 10 year)
86
87If the locale never uses daylight saving time, set this to nil."
88 :type 'sexp
89 :group 'calendar-dst)
90
91;;; More defcustoms below.
92
93
3e03d7c7 94(defvar calendar-current-time-zone-cache nil
ed589f9a 95 "Cache for result of `calendar-current-time-zone'.")
76db8823
GM
96;; It gets eval'd, eg by calendar-dst-starts.
97;;;###autoload
98(put 'calendar-current-time-zone-cache 'risky-local-variable t)
3e03d7c7
JB
99
100(defvar calendar-system-time-basis
101 (calendar-absolute-from-gregorian '(1 1 1970))
102 "Absolute date of starting date of system clock.")
103
3e03d7c7
JB
104(defun calendar-absolute-from-time (x utc-diff)
105 "Absolute local date of time X; local time is UTC-DIFF seconds from UTC.
106
107X is (HIGH . LOW) or (HIGH LOW . IGNORED) where HIGH and LOW are the
108high and low 16 bits, respectively, of the number of seconds since
1091970-01-01 00:00:00 UTC, ignoring leap seconds.
110
111Returns the pair (ABS-DATE . SECONDS) where SECONDS after local midnight on
112absolute date ABS-DATE is the equivalent moment to X."
113 (let* ((h (car x))
71ea27ee 114 (xtail (cdr x))
3e03d7c7 115 (l (+ utc-diff (if (numberp xtail) xtail (car xtail))))
4cc1b78a 116 (u (+ (* 512 (mod h 675)) (floor l 128))))
3e03d7c7
JB
117 ;; Overflow is a terrible thing!
118 (cons (+ calendar-system-time-basis
71ea27ee
GM
119 ;; floor((2^16 h +l) / (60*60*24))
120 (* 512 (floor h 675)) (floor u 675))
121 ;; (2^16 h +l) mod (60*60*24)
122 (+ (* (mod u 675) 128) (mod l 128)))))
3e03d7c7
JB
123
124(defun calendar-time-from-absolute (abs-date s)
125 "Time of absolute date ABS-DATE, S seconds after midnight.
126
ec9b5635 127Returns the list (HIGH LOW) where HIGH and LOW are the high and low
3e03d7c7
JB
12816 bits, respectively, of the number of seconds 1970-01-01 00:00:00 UTC,
129ignoring leap seconds, that is the equivalent moment to S seconds after
130midnight UTC on absolute date ABS-DATE."
131 (let* ((a (- abs-date calendar-system-time-basis))
4cc1b78a 132 (u (+ (* 163 (mod a 512)) (floor s 128))))
3e03d7c7 133 ;; Overflow is a terrible thing!
ec9b5635 134 (list
3ac14ca0 135 ;; floor((60*60*24*a + s) / 2^16)
4cc1b78a 136 (+ a (* 163 (floor a 512)) (floor u 512))
3ac14ca0 137 ;; (60*60*24*a + s) mod 2^16
4cc1b78a 138 (+ (* 128 (mod u 512)) (mod s 128)))))
3e03d7c7
JB
139
140(defun calendar-next-time-zone-transition (time)
141 "Return the time of the next time zone transition after TIME.
311cc551 142Both TIME and the result are acceptable arguments to `current-time-zone'.
3e03d7c7 143Return nil if no such transition can be found."
fd32e5b9
GM
144 (let* ((base 65536) ; 2^16 = base of current-time output
145 (quarter-multiple 120) ; approx = (seconds per quarter year) / base
71ea27ee
GM
146 (time-zone (current-time-zone time))
147 (time-utc-diff (car time-zone))
3e03d7c7 148 hi
71ea27ee 149 hi-zone
3e03d7c7
JB
150 (hi-utc-diff time-utc-diff)
151 (quarters '(2 1 3)))
152 ;; Heuristic: probe the time zone offset in the next three calendar
153 ;; quarters, looking for a time zone offset different from TIME.
154 (while (and quarters (eq time-utc-diff hi-utc-diff))
4b8683c7
GM
155 (setq hi (cons (+ (car time) (* (car quarters) quarter-multiple)) 0)
156 hi-zone (current-time-zone hi)
157 hi-utc-diff (car hi-zone)
158 quarters (cdr quarters)))
3e03d7c7
JB
159 (and
160 time-utc-diff
161 hi-utc-diff
162 (not (eq time-utc-diff hi-utc-diff))
163 ;; Now HI is after the next time zone transition.
164 ;; Set LO to TIME, and then binary search to increase LO and decrease HI
165 ;; until LO is just before and HI is just after the time zone transition.
166 (let* ((tail (cdr time))
71ea27ee
GM
167 (lo (cons (car time) (if (numberp tail) tail (car tail))))
168 probe)
3e03d7c7 169 (while
71ea27ee
GM
170 ;; Set PROBE to halfway between LO and HI, rounding down.
171 ;; If PROBE equals LO, we are done.
172 (let* ((lsum (+ (cdr lo) (cdr hi)))
173 (hsum (+ (car lo) (car hi) (/ lsum base)))
174 (hsumodd (logand 1 hsum)))
175 (setq probe (cons (/ (- hsum hsumodd) 2)
176 (/ (+ (* hsumodd base) (% lsum base)) 2)))
177 (not (equal lo probe)))
178 ;; Set either LO or HI to PROBE, depending on probe results.
179 (if (eq (car (current-time-zone probe)) hi-utc-diff)
180 (setq hi probe)
181 (setq lo probe)))
3e03d7c7
JB
182 hi))))
183
d80c2c18 184(autoload 'calendar-persian-to-absolute "cal-persia")
06e3b7ae 185
3e03d7c7
JB
186(defun calendar-time-zone-daylight-rules (abs-date utc-diff)
187 "Return daylight transition rule for ABS-DATE, UTC-DIFF sec offset from UTC.
e716fd62
CY
188ABS-DATE must specify a day that contains a daylight saving transition.
189The result has the proper form for `calendar-daylight-savings-starts'."
3e03d7c7 190 (let* ((date (calendar-gregorian-from-absolute abs-date))
71ea27ee 191 (weekday (% abs-date 7))
e803eab7
GM
192 (m (calendar-extract-month date))
193 (d (calendar-extract-day date))
194 (y (calendar-extract-year date))
3e03d7c7 195 (last (calendar-last-day-of-month m y))
ff35f3b8
GM
196 j rlist
197 (candidate-rules ; these return Gregorian dates
71ea27ee
GM
198 (append
199 ;; Day D of month M.
ff35f3b8 200 `((list ,m ,d year))
71ea27ee 201 ;; The first WEEKDAY of month M.
3e03d7c7 202 (if (< d 8)
ff35f3b8 203 `((calendar-nth-named-day 1 ,weekday ,m year)))
71ea27ee 204 ;; The last WEEKDAY of month M.
3e03d7c7 205 (if (> d (- last 7))
ff35f3b8
GM
206 `((calendar-nth-named-day -1 ,weekday ,m year)))
207 (progn
208 ;; The first WEEKDAY after day J of month M, for D-6 < J <= D.
209 (setq j (1- (max 2 (- d 6))))
210 (while (<= (setq j (1+ j)) (min d (- last 8)))
211 (push `(calendar-nth-named-day 1 ,weekday ,m year ,j) rlist))
212 rlist)
71ea27ee 213 ;; 01-01 and 07-01 for this year's Persian calendar.
ff35f3b8 214 ;; FIXME what does the Persian calendar have to do with this?
84cb770d
GM
215 (and (= m 3) (memq d '(20 21))
216 '((calendar-gregorian-from-absolute
217 (calendar-persian-to-absolute `(1 1 ,(- year 621))))))
218 (and (= m 9) (memq d '(22 23))
219 '((calendar-gregorian-from-absolute
220 (calendar-persian-to-absolute `(7 1 ,(- year 621))))))))
fd32e5b9 221 (prevday-sec (- -1 utc-diff)) ; last sec of previous local day
ff35f3b8
GM
222 (year (1+ y))
223 new-rules)
6bc457fe 224 ;; Scan through the next few years until only one rule remains.
ff35f3b8
GM
225 (while (cdr candidate-rules)
226 (dolist (rule candidate-rules)
227 ;; The rule we return should give a Gregorian date, but here
228 ;; we require an absolute date. The following is for efficiency.
229 (setq date (cond ((eq (car rule) 'calendar-nth-named-day)
230 (eval (cons 'calendar-nth-named-absday (cdr rule))))
231 ((eq (car rule) 'calendar-gregorian-from-absolute)
b27c3bc6 232 (eval (cadr rule)))
ff35f3b8
GM
233 (t (calendar-absolute-from-gregorian (eval rule)))))
234 (or (equal (current-time-zone
235 (calendar-time-from-absolute date prevday-sec))
236 (current-time-zone
237 (calendar-time-from-absolute (1+ date) prevday-sec)))
238 (setq new-rules (cons rule new-rules))))
239 ;; If no rules remain, just use the first candidate rule;
240 ;; it's wrong in general, but it's right for at least one year.
241 (setq candidate-rules (if new-rules (nreverse new-rules)
242 (list (car candidate-rules)))
4f1c166c
GM
243 new-rules nil
244 year (1+ year)))
6bc457fe 245 (car candidate-rules)))
3e03d7c7 246
cd72c399
GM
247;; TODO it might be better to extract this information directly from
248;; the system timezone database. But cross-platform...?
249;; See thread
250;; http://lists.gnu.org/archive/html/emacs-pretest-bug/2006-11/msg00060.html
251(defun calendar-dst-find-data (&optional time)
e716fd62 252 "Find data on the first daylight saving time transitions after TIME.
cd72c399
GM
253TIME defaults to `current-time'. Return value is as described
254for `calendar-current-time-zone'."
255 (let* ((t0 (or time (current-time)))
256 (t0-zone (current-time-zone t0))
257 (t0-utc-diff (car t0-zone))
4b8683c7 258 (t0-name (cadr t0-zone)))
cd72c399
GM
259 (if (not t0-utc-diff)
260 ;; Little or no time zone information is available.
261 (list nil nil t0-name t0-name nil nil nil nil)
262 (let* ((t1 (calendar-next-time-zone-transition t0))
263 (t2 (and t1 (calendar-next-time-zone-transition t1))))
264 (if (not t2)
e716fd62 265 ;; This locale does not have daylight saving time.
cd72c399 266 (list (/ t0-utc-diff 60) 0 t0-name t0-name nil nil 0 0)
e716fd62 267 ;; Use heuristics to find daylight saving parameters.
cd72c399
GM
268 (let* ((t1-zone (current-time-zone t1))
269 (t1-utc-diff (car t1-zone))
4b8683c7 270 (t1-name (cadr t1-zone))
cd72c399
GM
271 (t1-date-sec (calendar-absolute-from-time t1 t0-utc-diff))
272 (t2-date-sec (calendar-absolute-from-time t2 t1-utc-diff))
273 ;; TODO When calendar-dst-check-each-year-flag is non-nil,
274 ;; the rules can be simpler than they currently are.
275 (t1-rules (calendar-time-zone-daylight-rules
276 (car t1-date-sec) t0-utc-diff))
277 (t2-rules (calendar-time-zone-daylight-rules
278 (car t2-date-sec) t1-utc-diff))
279 (t1-time (/ (cdr t1-date-sec) 60))
280 (t2-time (/ (cdr t2-date-sec) 60)))
281 (cons
282 (/ (min t0-utc-diff t1-utc-diff) 60)
283 (cons
284 (/ (abs (- t0-utc-diff t1-utc-diff)) 60)
285 (if (< t0-utc-diff t1-utc-diff)
286 (list t0-name t1-name t1-rules t2-rules t1-time t2-time)
287 (list t1-name t0-name t2-rules t1-rules t2-time t1-time)
288 )))))))))
289
290(defvar calendar-dst-transition-cache nil
e716fd62 291 "Internal cal-dst variable storing date of daylight saving time transitions.
cd72c399
GM
292Value is a list with elements of the form (YEAR START END), where
293START and END are expressions that when evaluated return the
311cc551 294start and end dates (respectively) for DST in YEAR. Used by the
cd72c399
GM
295function `calendar-dst-find-startend'.")
296
297(defun calendar-dst-find-startend (year)
e716fd62 298 "Find the dates in YEAR on which daylight saving time starts and ends.
cd72c399
GM
299Returns a list (YEAR START END), where START and END are
300expressions that when evaluated return the start and end dates,
301respectively. This function first attempts to use pre-calculated
302data from `calendar-dst-transition-cache', otherwise it calls
325c2dd1
GM
303`calendar-dst-find-data' (and adds the results to the cache).
304If dates in YEAR cannot be handled by `encode-time' (e.g. if they
305are too large to be represented as a lisp integer), then rather
306than an error this function returns the result appropriate for
307the current year."
cd72c399
GM
308 (let ((e (assoc year calendar-dst-transition-cache))
309 f)
310 (or e
311 (progn
325c2dd1
GM
312 (setq e (calendar-dst-find-data
313 (condition-case nil
314 (encode-time 1 0 0 1 1 year)
315 (error
316 (encode-time 1 0 0 1 1 (nth 5 (decode-time))))))
cd72c399
GM
317 f (nth 4 e)
318 e (list year f (nth 5 e))
319 calendar-dst-transition-cache
320 (append calendar-dst-transition-cache (list e)))
321 e))))
322
3e03d7c7
JB
323(defun calendar-current-time-zone ()
324 "Return UTC difference, dst offset, names and rules for current time zone.
325
6bc457fe
PE
326Returns (UTC-DIFF DST-OFFSET STD-ZONE DST-ZONE DST-STARTS DST-ENDS
327DST-STARTS-TIME DST-ENDS-TIME), based on a heuristic probing of what the
328system knows:
3e03d7c7
JB
329
330UTC-DIFF is an integer specifying the number of minutes difference between
331 standard time in the current time zone and Coordinated Universal Time
332 (Greenwich Mean Time). A negative value means west of Greenwich.
e716fd62 333DST-OFFSET is an integer giving the daylight saving time offset in minutes.
3e03d7c7
JB
334STD-ZONE is a string giving the name of the time zone when no seasonal time
335 adjustment is in effect.
336DST-ZONE is a string giving the name of the time zone when there is a seasonal
337 time adjustment in effect.
338DST-STARTS and DST-ENDS are sexps in the variable `year' giving the daylight
e716fd62 339 saving time start and end rules, in the form expected by
3e03d7c7 340 `calendar-daylight-savings-starts'.
6bc457fe 341DST-STARTS-TIME and DST-ENDS-TIME are integers giving the number of minutes
e716fd62 342 after midnight that daylight saving time starts and ends.
3e03d7c7 343
6bc457fe
PE
344If the local area does not use a seasonal time adjustment, STD-ZONE and
345DST-ZONE are equal, and all the DST-* integer variables are 0.
3e03d7c7
JB
346
347Some operating systems cannot provide all this information to Emacs; in this
348case, `calendar-current-time-zone' returns a list containing nil for the data
349it can't find."
3d8b9024
AS
350 (or calendar-current-time-zone-cache
351 (setq calendar-current-time-zone-cache (calendar-dst-find-data))))
3e03d7c7 352
ec1ee609
GM
353
354;; Following options should be set based on conditions when the code
355;; is invoked, so are not suitable for dumping into loaddefs.el. They
356;; default to US Eastern time if time zone info is not available.
3e03d7c7
JB
357
358(calendar-current-time-zone)
359
ec1ee609 360(defcustom calendar-time-zone (or (car calendar-current-time-zone-cache) -300)
311cc551 361 "Number of minutes difference between local standard time and UTC.
ec1ee609
GM
362For example, -300 for New York City, -480 for Los Angeles."
363 :type 'integer
364 :group 'calendar-dst)
3e03d7c7 365
ec1ee609 366(defcustom calendar-daylight-time-offset
4b8683c7 367 (or (cadr calendar-current-time-zone-cache) 60)
ec1ee609
GM
368 "Number of minutes difference between daylight saving and standard time.
369If the locale never uses daylight saving time, set this to 0."
370 :type 'integer
371 :group 'calendar-dst)
3e03d7c7 372
ec1ee609 373(defcustom calendar-standard-time-zone-name
4b8683c7 374 (or (nth 2 calendar-current-time-zone-cache) "EST")
ec1ee609
GM
375 "Abbreviated name of standard time zone at `calendar-location-name'.
376For example, \"EST\" in New York City, \"PST\" for Los Angeles."
377 :type 'string
378 :group 'calendar-dst)
3e03d7c7 379
ec1ee609 380(defcustom calendar-daylight-time-zone-name
4b8683c7 381 (or (nth 3 calendar-current-time-zone-cache) "EDT")
ec1ee609
GM
382 "Abbreviated name of daylight saving time zone at `calendar-location-name'.
383For example, \"EDT\" in New York City, \"PDT\" for Los Angeles."
384 :type 'string
385 :group 'calendar-dst)
386
387(defcustom calendar-daylight-savings-starts-time
4b8683c7 388 (or (nth 6 calendar-current-time-zone-cache) 120)
ec1ee609
GM
389 "Number of minutes after midnight that daylight saving time starts."
390 :type 'integer
391 :group 'calendar-dst)
392
393(defcustom calendar-daylight-savings-ends-time
4b8683c7 394 (or (nth 7 calendar-current-time-zone-cache)
ec1ee609
GM
395 calendar-daylight-savings-starts-time)
396 "Number of minutes after midnight that daylight saving time ends."
397 :type 'integer
398 :group 'calendar-dst)
a1506d29 399
cd72c399
GM
400
401(defun calendar-dst-starts (year)
e716fd62 402 "Return the date of YEAR on which daylight saving time starts.
cd72c399
GM
403This function respects the value of `calendar-dst-check-each-year-flag'."
404 (or (let ((expr (if calendar-dst-check-each-year-flag
405 (cadr (calendar-dst-find-startend year))
406 (nth 4 calendar-current-time-zone-cache))))
407 (if expr (eval expr)))
71ea27ee 408 ;; New US rules commencing 2007. ftp://elsie.nci.nih.gov/pub/.
cd72c399 409 (and (not (zerop calendar-daylight-time-offset))
ed589f9a 410 (calendar-nth-named-day 2 0 3 year))))
cd72c399
GM
411
412(defun calendar-dst-ends (year)
e716fd62 413 "Return the date of YEAR on which daylight saving time ends.
cd72c399
GM
414This function respects the value of `calendar-dst-check-each-year-flag'."
415 (or (let ((expr (if calendar-dst-check-each-year-flag
416 (nth 2 (calendar-dst-find-startend year))
417 (nth 5 calendar-current-time-zone-cache))))
418 (if expr (eval expr)))
71ea27ee 419 ;; New US rules commencing 2007. ftp://elsie.nci.nih.gov/pub/.
cd72c399 420 (and (not (zerop calendar-daylight-time-offset))
ed589f9a 421 (calendar-nth-named-day 1 0 11 year))))
cd72c399 422
76db8823 423;; used by calc, solar.
ec230951 424(defun dst-in-effect (date)
e716fd62 425 "True if on absolute DATE daylight saving time is in effect.
021edd45 426Fractional part of DATE is local standard time of day."
e803eab7 427 (let* ((year (calendar-extract-year
ec230951 428 (calendar-gregorian-from-absolute (floor date))))
021edd45
ER
429 (dst-starts-gregorian (eval calendar-daylight-savings-starts))
430 (dst-ends-gregorian (eval calendar-daylight-savings-ends))
431 (dst-starts (and dst-starts-gregorian
ec230951 432 (+ (calendar-absolute-from-gregorian
021edd45 433 dst-starts-gregorian)
ec230951
ER
434 (/ calendar-daylight-savings-starts-time
435 60.0 24.0))))
021edd45 436 (dst-ends (and dst-ends-gregorian
ec230951 437 (+ (calendar-absolute-from-gregorian
021edd45 438 dst-ends-gregorian)
ec230951
ER
439 (/ (- calendar-daylight-savings-ends-time
440 calendar-daylight-time-offset)
441 60.0 24.0)))))
021edd45
ER
442 (and dst-starts dst-ends
443 (if (< dst-starts dst-ends)
444 (and (<= dst-starts date) (< date dst-ends))
445 (or (<= dst-starts date) (< date dst-ends))))))
ec230951 446
76db8823 447;; used by calc, lunar, solar.
bc4f7f3d 448(defun dst-adjust-time (date time)
ec230951
ER
449 "Adjust, to account for dst on DATE, decimal fraction standard TIME.
450Returns a list (date adj-time zone) where `date' and `adj-time' are the values
451adjusted for `zone'; here `date' is a list (month day year), `adj-time' is a
452decimal fraction time, and `zone' is a string.
453
e716fd62 454Conversion to daylight saving time is done according to
ec230951
ER
455`calendar-daylight-savings-starts', `calendar-daylight-savings-ends',
456`calendar-daylight-savings-starts-time',
06e3b7ae 457`calendar-daylight-savings-ends-time', and `calendar-daylight-time-offset'."
ec230951 458 (let* ((rounded-abs-date (+ (calendar-absolute-from-gregorian date)
71ea27ee 459 (/ (round (* 60 time)) 60.0 24.0)))
ec230951 460 (dst (dst-in-effect rounded-abs-date))
71ea27ee
GM
461 (time-zone (if dst
462 calendar-daylight-time-zone-name
463 calendar-standard-time-zone-name))
464 (time (+ rounded-abs-date
ec230951
ER
465 (if dst (/ calendar-daylight-time-offset 24.0 60.0) 0))))
466 (list (calendar-gregorian-from-absolute (truncate time))
467 (* 24.0 (- time (truncate time)))
468 time-zone)))
469
3e03d7c7
JB
470(provide 'cal-dst)
471
472;;; cal-dst.el ends here