summaryrefslogtreecommitdiff
path: root/lisp/calendar
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1997-05-20 05:17:49 +0000
committerRichard M. Stallman <rms@gnu.org>1997-05-20 05:17:49 +0000
commit151eeaa7c4f9ceea7b9c1560a13b9639b73a7a2f (patch)
treec11641c72b841879f604e033ba3ed89cee1d4afe /lisp/calendar
parent4abfba1faa600d0928f0a807ef803fc2f78f4bd5 (diff)
downloademacs-151eeaa7c4f9ceea7b9c1560a13b9639b73a7a2f.tar.gz
(holiday-float): Rewritten to fix bug when base date
of holiday and holiday date are in different months.
Diffstat (limited to 'lisp/calendar')
-rw-r--r--lisp/calendar/holidays.el51
1 files 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.