From: Richard M. Stallman Date: Tue, 20 May 1997 05:17:49 +0000 (+0000) Subject: (holiday-float): Rewritten to fix bug when base date X-Git-Tag: emacs-20.1~2054 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=151eeaa7c4f9ceea7b9c1560a13b9639b73a7a2f;p=emacs.git (holiday-float): Rewritten to fix bug when base date of holiday and holiday date are in different months. --- diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el index e7077e96ecf..eeae46b9401 100644 --- a/lisp/calendar/holidays.el +++ b/lisp/calendar/holidays.el @@ -310,20 +310,57 @@ STRING)). Returns nil if it is not visible in the current calendar window." (list (list (list month day y) string))))) (defun holiday-float (month dayname n string &optional day) - "Holiday on MONTH, DAYNAME (Nth occurrence, Gregorian) called STRING. + "Holiday on MONTH, DAYNAME (Nth occurrence) called STRING. If the Nth DAYNAME in MONTH is visible, the value returned is the list \(((MONTH DAY year) STRING)). If N<0, count backward from the end of MONTH. -An optional parameter DAY means the Nth DAYNAME after/before MONTH DAY. +An optional parameter DAY means the Nth DAYNAME on or after/before MONTH DAY. Returns nil if it is not visible in the current calendar window." - (let ((m displayed-month) - (y displayed-year)) - (increment-calendar-month m y (- 11 month)) - (if (> m 9) - (list (list (calendar-nth-named-day n dayname month y day) string))))) +;; This is messy because the holiday may be visible, while the date on which +;; it is based is not. For example, the first Monday after December 30 may be +;; visible when January is not. For large values of |n| the problem is more +;; grotesque. If we didn't have to worry about such cases, we could just use + +;; (let ((m displayed-month) +;; (y displayed-year)) +;; (increment-calendar-month m y (- 11 month)) +;; (if (> m 9); month in year y is visible +;; (list (list (calendar-nth-named-day n dayname month y day) string))))) + +;; which is the way the function was originally written. + + (let* ((m1 displayed-month) + (y1 displayed-year) + (m2 m1) + (y2 y1)) + (increment-calendar-month m1 y1 -1) + (increment-calendar-month m2 y2 1) + (let* ((d1; first possible base date for holiday + (+ (calendar-nth-named-absday 1 dayname m1 y1) + (* -7 n) + (if (> n 0) 1 -7))) + (d2; last possible base date for holiday + (+ (calendar-nth-named-absday -1 dayname m2 y2) + (* -7 n) + (if (> n 0) 7 -1))) + (y1 (extract-calendar-year (calendar-gregorian-from-absolute d1))) + (y2 (extract-calendar-year (calendar-gregorian-from-absolute d2))) + (y; year of base date + (if (or (= y1 y2) (> month 9)) + y1 + y2)) + (d; day of base date + (or day (if (> n 0) + 1 + (calendar-last-day-of-month month y)))) + (date; base date for holiday + (calendar-absolute-from-gregorian (list month d y)))) + (if (and (<= d1 date) (<= date d2)) + (list (list (calendar-nth-named-day n dayname month y d) + string)))))) (defun holiday-sexp (sexp string) "Sexp holiday for dates in the calendar window.