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)))