Function: calendar-gregorian-from-absolute

calendar-gregorian-from-absolute is a byte-compiled function defined in calendar.el.gz.

Signature

(calendar-gregorian-from-absolute DATE)

Documentation

Compute the list (month day year) corresponding to the absolute DATE.

The absolute date is the number of days elapsed since the (imaginary) Gregorian date Sunday, December 31, 1 BC. This function does not handle dates in years BC.

Source Code

;; Defined in /usr/src/emacs/lisp/calendar/calendar.el.gz
;; The following version of calendar-gregorian-from-absolute is preferred for
;; reasons of clarity, BUT it's much slower than the version that follows it.

;;(defun calendar-gregorian-from-absolute (date)
;;  "Compute the list (month day year) corresponding to the absolute DATE.
;;The absolute date is the number of days elapsed since the (imaginary)
;;Gregorian date Sunday, December 31, 1 BC."
;;  (let* ((approx (/ date 366)) ; approximation from below
;;         (year                ; search forward from the approximation
;;          (+ approx
;;             (calendar-sum y approx
;;                 (>= date (calendar-absolute-from-gregorian (list 1 1 (1+ y))))
;;                  1)))
;;         (month                         ; search forward from January
;;          (1+ (calendar-sum m 1
;;                   (> date
;;                      (calendar-absolute-from-gregorian
;;                       (list m (calendar-last-day-of-month m year) year)))
;;                   1)))
;;         (day                      ; calculate the day by subtraction
;;          (- date
;;             (1- (calendar-absolute-from-gregorian (list month 1 year))))))
;;    (list month day year)))

(defun calendar-gregorian-from-absolute (date)
  "Compute the list (month day year) corresponding to the absolute DATE.
The absolute date is the number of days elapsed since the (imaginary)
Gregorian date Sunday, December 31, 1 BC.  This function does not
handle dates in years BC."
  ;; For an explanation, see the footnote on page 384 of "Calendrical
  ;; Calculations, Part II: Three Historical Calendars" by
  ;; E. M. Reingold, N. Dershowitz, and S. M.  Clamen,
  ;; Software--Practice and Experience, Volume 23, Number 4 (April,
  ;; 1993), pages 383-404 <https://doi.org/10.1002/spe.4380230404>
  ;; <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.42.6421&rep=rep1&type=pdf>.
  (let* ((d0 (1- date))
         (n400 (/ d0 146097))
         (d1 (% d0 146097))
         (n100 (/ d1 36524))
         (d2 (% d1 36524))
         (n4 (/ d2 1461))
         (d3 (% d2 1461))
         (n1 (/ d3 365))
         (day (1+ (% d3 365)))
         (year (+ (* 400 n400) (* 100 n100) (* n4 4) n1))
         (month 1)
         mdays)
    (if (or (= n100 4) (= n1 4))
        (list 12 31 year)
      (setq year (1+ year))
      (while (< (setq mdays (calendar-last-day-of-month month year)) day)
        (setq day (- day mdays)
              month (1+ month)))
      (list month day year))))