Search code examples
emacselisp

Function to determine holiday in elisp


It's there any function to determine current system date is holiday or not in elisp.

function like this.

(is-holiday (current-time))

Solution

  • The answer requires that the user set up a calendar of predefined holidays, like this example. I have included a test holiday for May 9 -- if the user wishes to test out this function on any day other than May 9, the user may wish to change the Arbitrary Test Holiday to whatever day the test is being performed -- after the function has been tested, the test entry can be removed.

    For examples of how to format the holidays, please refer to the doc-string for the variable calendar-holidays within the library holidays.el -- e.g., holiday-fixed; holiday-float; holiday-sexp; (lunar-phases); (solar-equinoxes-solstices); holiday-hebrew; holiday-islamic; holiday-bahai; holiday-julian; holiday-chinese; etc.

    How can you try out this example?: Block/copy/paste the code into your *scratch* buffer; and type M-x eval-buffer RET; and then type M-x is-holiday RET. It is a fully functional working draft. If you decide that you don't like it after you try it, just restart Emacs and you'll be back to where you were before you tried it.

    The testing that was performed was done with the most recent public release of Emacs: GNU Emacs 24.4.1 (x86_64-apple-darwin10.8.0, NS apple-appkit-1038.36) of 2014-10-20 on builder10-6.porkrind.org.

    (require 'holidays)
    
    (defcustom my-custom-holiday-list (mapcar 'purecopy '(
      (holiday-fixed 1 1 "New Year's Day")
      (holiday-float 1 1 3 "Martin Luther King Day")
      (holiday-float 2 1 3 "President's Day")
      (holiday-float 5 1 -1 "Memorial Day")
      ;; ARBITRARY TEST HOLIDAY -- MAY 9
      (holiday-fixed 5 9 "Arbitrary Test Holiday -- May 9")
      (holiday-fixed 7 4 "Independence Day")
      (holiday-float 9 1 1 "Labor Day")
      (holiday-float 10 1 2 "Columbus Day")
      (holiday-fixed 11 11 "Veteran's Day")
      (holiday-float 11 4 4 "Thanksgiving")
      (holiday-fixed 12 25 "Christmas")
      (solar-equinoxes-solstices)
      (holiday-sexp calendar-daylight-savings-starts
        (format "Daylight Saving Time Begins %s"
          (solar-time-string
            (/ calendar-daylight-savings-starts-time (float 60))
            calendar-standard-time-zone-name)))
      (holiday-sexp calendar-daylight-savings-ends
          (format "Daylight Saving Time Ends %s"
           (solar-time-string
             (/ calendar-daylight-savings-ends-time (float 60))
             calendar-daylight-time-zone-name))) ))
      "Custom holidays defined by the user."
      :type 'sexp
      :group 'holidays)
    
    (defun is-holiday ()
      "Is today a holiday?"
    (interactive)
      (let* (
          (d1 (time-to-days (current-time)))
          (date (calendar-gregorian-from-absolute d1))
          ee
          res-holidays
          (displayed-month (nth 0 date))
          (displayed-year (nth 2 date))
          (holiday-list
            (dolist (p my-custom-holiday-list res-holidays)
              (let* (h)
               (when (setq h (eval p))
                 (setq res-holidays (append h res-holidays)))))) )
        (mapcar
          (lambda (x)
            (let ((txt (format "%s -- %s" (car x) (car (cdr x)))))
              (when (eq d1 (calendar-absolute-from-gregorian (car x)))
                (push txt ee))))
          holiday-list)
        (if ee
          (message "The following holiday(s) is/are today:  %s" (nreverse ee))
          (message "Today is not a holiday."))))