From 151eeaa7c4f9ceea7b9c1560a13b9639b73a7a2f Mon Sep 17 00:00:00 2001 From: "Richard M. Stallman" Date: Tue, 20 May 1997 05:17:49 +0000 Subject: [PATCH] (holiday-float): Rewritten to fix bug when base date of holiday and holiday date are in different months. --- lisp/calendar/holidays.el | 51 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) 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. -- 2.11.4.GIT