]> code.delx.au - gnu-emacs/blobdiff - lisp/calendar/cal-dst.el
(timeclock-use-elapsed): Added a new variable, which causes timeclock
[gnu-emacs] / lisp / calendar / cal-dst.el
index 598af905d99f8a2420780b572e50bcf66bcfeb7c..62327a99c65591ee88866aab93913a95dc7e3148 100644 (file)
@@ -1,9 +1,11 @@
-;;; cal-dst.el --- calendar functions for daylight savings rules.
+;;; cal-dst.el --- calendar functions for daylight savings rules
 
-;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 1995, 1996, 2001, 2002, 2003, 2004, 2005,
+;;   2006  Free Software Foundation, Inc.
 
 ;; Author: Paul Eggert <eggert@twinsun.com>
 ;;     Edward M. Reingold <reingold@cs.uiuc.edu>
+;; Maintainer: Glenn Morris <rgm@gnu.org>
 ;; Keywords: calendar
 ;; Human-Keywords: daylight savings time, calendar, diary, holidays
 
@@ -20,8 +22,9 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
@@ -37,6 +40,7 @@
 ;;; Code:
 
 (require 'calendar)
+(require 'cal-persia)
 
 (defvar calendar-current-time-zone-cache nil
   "Cache for result of calendar-current-time-zone.")
@@ -68,14 +72,14 @@ absolute date ABS-DATE is the equivalent moment to X."
 (defun calendar-time-from-absolute (abs-date s)
   "Time of absolute date ABS-DATE, S seconds after midnight.
 
-Returns the pair (HIGH . LOW) where HIGH and LOW are the high and low
+Returns the list (HIGH LOW) where HIGH and LOW are the high and low
 16 bits, respectively, of the number of seconds 1970-01-01 00:00:00 UTC,
 ignoring leap seconds, that is the equivalent moment to S seconds after
 midnight UTC on absolute date ABS-DATE."
   (let* ((a (- abs-date calendar-system-time-basis))
          (u (+ (* 163 (mod a 512)) (floor s 128))))
     ;; Overflow is a terrible thing!
-    (cons
+    (list
      ;; floor((60*60*24*a + s) / 2^16)
      (+ a (* 163 (floor a 512)) (floor u 512))
      ;; (60*60*24*a + s) mod 2^16
@@ -127,7 +131,7 @@ Return nil if no such transition can be found."
 
 (defun calendar-time-zone-daylight-rules (abs-date utc-diff)
   "Return daylight transition rule for ABS-DATE, UTC-DIFF sec offset from UTC.
-ABS-DIFF must specify a day that contains a daylight savings transition.
+ABS-DATE must specify a day that contains a daylight savings transition.
 The result has the proper form for calendar-daylight-savings-starts'."
   (let* ((date (calendar-gregorian-from-absolute abs-date))
         (weekday (% abs-date 7))
@@ -152,7 +156,16 @@ The result has the proper form for calendar-daylight-savings-starts'."
                      (cons
                       (list 'calendar-nth-named-day 1 weekday m 'year j)
                       l)))
-            l)))
+            l)
+          ;; 01-01 and 07-01 for this year's Persian calendar.
+          (if (and (= m 3) (<= 20 d) (<= d 21))
+              '((calendar-gregorian-from-absolute
+                 (calendar-absolute-from-persian
+                  (list 1 1 (- year 621))))))
+          (if (and (= m 9) (<= 22 d) (<= d 23))
+              '((calendar-gregorian-from-absolute
+                 (calendar-absolute-from-persian
+                  (list 7 1 (- year 621))))))))
         (prevday-sec (- -1 utc-diff)) ;; last sec of previous local day
         (year (1+ y)))
     ;; Scan through the next few years until only one rule remains.
@@ -267,7 +280,7 @@ example, -300 for New York City, -480 for Los Angeles.")
 (defvar calendar-daylight-time-offset
   (or (car (cdr calendar-current-time-zone-cache)) 60)
   "*Number of minutes difference between daylight savings and standard time.
-  
+
 If the locale never uses daylight savings time, set this to 0.")
 
 (defvar calendar-standard-time-zone-name
@@ -279,7 +292,7 @@ For example, \"EST\" in New York City, \"PST\" for Los Angeles.")
   (or (car (nthcdr 3 calendar-current-time-zone-cache)) "EDT")
   "*Abbreviated name of daylight-savings time zone at `calendar-location-name'.
 For example, \"EDT\" in New York City, \"PDT\" for Los Angeles.")
-  
+
 ;;;###autoload
 (put 'calendar-daylight-savings-starts 'risky-local-variable t)
 (defvar calendar-daylight-savings-starts
@@ -320,11 +333,11 @@ For example, if daylight savings time ends on the last Sunday in October:
       '(calendar-nth-named-day -1 0 10 year)
 
 If the locale never uses daylight savings time, set this to nil.")
-  
+
 (defvar calendar-daylight-savings-starts-time
   (or (car (nthcdr 6 calendar-current-time-zone-cache)) 120)
   "*Number of minutes after midnight that daylight savings time starts.")
-  
+
 (defvar calendar-daylight-savings-ends-time
   (or (car (nthcdr 7 calendar-current-time-zone-cache))
       calendar-daylight-savings-starts-time)
@@ -332,27 +345,26 @@ If the locale never uses daylight savings time, set this to nil.")
 
 (defun dst-in-effect (date)
   "True if on absolute DATE daylight savings time is in effect.
-Fractional part of DATE is time of day."
+Fractional part of DATE is local standard time of day."
   (let* ((year (extract-calendar-year
                 (calendar-gregorian-from-absolute (floor date))))
-         (dst-starts (and (eval calendar-daylight-savings-starts)
+         (dst-starts-gregorian (eval calendar-daylight-savings-starts))
+         (dst-ends-gregorian (eval calendar-daylight-savings-ends))
+         (dst-starts (and dst-starts-gregorian
                           (+ (calendar-absolute-from-gregorian
-                              (eval calendar-daylight-savings-starts))
+                              dst-starts-gregorian)
                              (/ calendar-daylight-savings-starts-time
                                 60.0 24.0))))
-         (dst-ends (and (eval calendar-daylight-savings-ends)
+         (dst-ends (and dst-ends-gregorian
                         (+ (calendar-absolute-from-gregorian
-                            (eval calendar-daylight-savings-ends))
+                            dst-ends-gregorian)
                            (/ (- calendar-daylight-savings-ends-time
                                  calendar-daylight-time-offset)
                               60.0 24.0)))))
-    (and (and dst-starts dst-ends
-              (or (and (< dst-starts dst-ends);; northern hemi.
-                       (<= dst-starts date) (< date dst-ends))
-                  (and (< dst-ends dst-starts);; southern hemi.
-                       (<= dst-starts date) (< date dst-ends))
-                  (and dst-starts (not dst-ends) (<= dst-starts date))
-                  (and dst-ends (not dst-starts) (< date dst-ends)))))))
+    (and dst-starts dst-ends
+         (if (< dst-starts dst-ends)
+             (and (<= dst-starts date) (< date dst-ends))
+           (or (<= dst-starts date) (< date dst-ends))))))
 
 (defun dst-adjust-time (date time &optional style)
   "Adjust, to account for dst on DATE, decimal fraction standard TIME.
@@ -384,4 +396,5 @@ Conversion to daylight savings time is done according to
 
 (provide 'cal-dst)
 
+;;; arch-tag: a141d204-213c-4ca5-bdc6-f9df3aa92aad
 ;;; cal-dst.el ends here