Function: holiday-chinese

holiday-chinese is a byte-compiled function defined in cal-china.el.gz.

Signature

(holiday-chinese MONTH DAY STRING)

Documentation

Holiday on Chinese MONTH, DAY called STRING.

If MONTH, DAY (Chinese) is visible, returns corresponding Gregorian dates as a list of ((month day year) STRING). The leap month is skipped because only the earlier date is considered a holiday. Returns nil if it is not visible in the current calendar window.

Probably introduced at or before Emacs version 23.1.

Source Code

;; Defined in /usr/src/emacs/lisp/calendar/cal-china.el.gz
;;;###holiday-autoload
(defun holiday-chinese (month day string)
  "Holiday on Chinese MONTH, DAY called STRING.
If MONTH, DAY (Chinese) is visible, returns corresponding Gregorian
dates as a list of ((month day year) STRING).  The leap month is skipped
because only the earlier date is considered a holiday.  Returns nil if
it is not visible in the current calendar window."
  (let ((range (calendar-get-date-range t)) dates)
    ;; A basic optimization.  Chinese year can only change if
    ;; Jan or Feb are visible.  FIXME can we do more?
    (if (not (calendar-month-visible-p 1 1))
        ;; Simple form for when new years are not visible.
        (push
         (calendar-gregorian-from-absolute
          (+ (cadr (assoc month (calendar-chinese-year
                                 (calendar-extract-year (car range)))))
             (1- day)))
         dates)
      ;; This is calendar-nongregorian-date-visible-p adapted for
      ;; the form of chinese dates: (cycle year month day) as
      ;; opposed to (month day year).
      (let* ((start-date (calendar-absolute-from-gregorian (car range)))
             (end-date (calendar-absolute-from-gregorian (cdr range)))
             ;; Local date of first/last date in calendar window.
             (local-start (calendar-chinese-from-absolute start-date))
             (local-end (calendar-chinese-from-absolute end-date))
             (c1 (nth 0 local-start))
             (c2 (nth 0 local-end))
             (y1 (nth 1 local-start))
             (y2 (nth 1 local-end))
             (m1 (nth 2 local-start))
             (m2 (nth 2 local-end)))
        (if (= y1 y2)
            (push (list c1 y1 month day) dates)
          ;; In a large calendar range (e.g. 12 months), a local
          ;; month/day may appear twice and there may be three local
          ;; years, e.g. (holiday-chinese 1 1 "") in 2019/02-2020/01.
          (dotimes (i (- y2 y1 1))
            (push (list (if (>= (+ y1 i 1) 60) (1+ c1) c1)
                        (+ y1 i 1) month day)
                  dates))
          (when (>= month m1)
            (push (list c1 y1 month day) dates))
          (when (<= month m2)
            (push (list c2 y2 month day) dates)))
        (setq dates (mapcar (lambda (d) (calendar-gregorian-from-absolute
                                    (calendar-chinese-to-absolute d)))
                            dates))))
    (holiday-filter-visible-calendar (mapcar (lambda (d) (list d string)) dates))))