Function: holiday-float
holiday-float is a byte-compiled function defined in holidays.el.gz.
Signature
(holiday-float MONTH DAYNAME N STRING &optional DAY)
Documentation
Holiday called STRING on the Nth DAYNAME after/before MONTH DAY.
DAYNAME = 0 means Sunday, DAYNAME = 1 means Monday, and so on. DAY defaults to 1 if N > 0, and MONTH's last day otherwise.
If N > 0, use the Nth DAYNAME after MONTH DAY. If N < 0, use the Nth DAYNAME before MONTH DAY.
When MONTH DAY falls on DAYNAME, the holiday will be |N|-1 weeks before or after MONTH DAY. For example, with N = +1 (-1) the holiday falls on MONTH DAY, and with N = +2 (-2) the holiday falls 1 week after (before) MONTH DAY.
If the holiday is visible in the calendar window, returns a list (((month day year) STRING)). Otherwise returns nil.
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/holidays.el.gz
(defun holiday-float (month dayname n string &optional day)
"Holiday called STRING on the Nth DAYNAME after/before MONTH DAY.
DAYNAME = 0 means Sunday, DAYNAME = 1 means Monday, and so on. DAY
defaults to 1 if N > 0, and MONTH's last day otherwise.
If N > 0, use the Nth DAYNAME after MONTH DAY.
If N < 0, use the Nth DAYNAME before MONTH DAY.
When MONTH DAY falls on DAYNAME, the holiday will be |N|-1 weeks before
or after MONTH DAY. For example, with N = +1 (-1) the holiday falls on
MONTH DAY, and with N = +2 (-2) the holiday falls 1 week after (before)
MONTH DAY.
If the holiday is visible in the calendar window, returns a
list (((month day year) STRING)). Otherwise returns nil."
;; 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 the original version of this
;; function:
;; (let ((m displayed-month)
;; (y displayed-year))
;; (calendar-increment-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)))))
(pcase-let*
((`(,m1 ,y1 ,m2 ,y2) (calendar-get-month-range))
(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)))
(`(,d1m ,_ ,d1y) (calendar-gregorian-from-absolute d1))
(`(,d2m ,_ ,d2y) (calendar-gregorian-from-absolute d2)))
(let (years dates date d)
;; possible years of base date
(if (or (= d1y d2y) (>= month d1m)) (push d1y years))
(if (and (/= d1y d2y) (<= month d2m)) (push d2y years))
(dolist (y years)
(setq d (or day (if (> n 0) ; day of base date
1
(calendar-last-day-of-month month y))))
(setq date ; base date for holiday
(calendar-absolute-from-gregorian (list month d y)))
(when (and (<= d1 date) (<= date d2))
(push (list (calendar-nth-named-day n dayname month y d)
string)
dates)))
dates)))