guile-elisp bootstrap (lisp)
[bpt/emacs.git] / lisp / calendar / cal-hebrew.el
CommitLineData
3afbc435 1;;; cal-hebrew.el --- calendar functions for the Hebrew calendar
4b112ac4 2
ba318903 3;; Copyright (C) 1995, 1997, 2001-2014 Free Software Foundation, Inc.
4b112ac4 4
85d0ba86 5;; Author: Nachum Dershowitz <nachum@cs.uiuc.edu>
6b789b4b 6;; Edward M. Reingold <reingold@cs.uiuc.edu>
dbfca9c4 7;; Maintainer: Glenn Morris <rgm@gnu.org>
4b112ac4
ER
8;; Keywords: calendar
9;; Human-Keywords: Hebrew calendar, calendar, diary
bd78fa1d 10;; Package: calendar
4b112ac4
ER
11
12;; This file is part of GNU Emacs.
13
2ed66575 14;; GNU Emacs is free software: you can redistribute it and/or modify
4b112ac4 15;; it under the terms of the GNU General Public License as published by
2ed66575
GM
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
4b112ac4
ER
18
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
2ed66575 25;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
4b112ac4
ER
26
27;;; Commentary:
28
618c03c1 29;; See calendar.el.
a96a5fca 30
4b112ac4
ER
31;;; Code:
32
da3fc020 33(require 'calendar)
4b112ac4 34
1a9f2b77
GM
35(define-obsolete-variable-alias 'diary-sabbath-candles-minutes
36 'diary-hebrew-sabbath-candles-minutes "23.1")
37
87e1e9cd
GM
38(defcustom diary-hebrew-sabbath-candles-minutes 18
39 "Number of minutes before sunset for sabbath candle lighting.
40Used by `diary-hebrew-sabbath-candles'."
41 :group 'diary
42 :type 'integer
43 :version "21.1")
44
87e1e9cd
GM
45;; End of user options.
46
8fc9e5a0 47(defun calendar-hebrew-leap-year-p (year)
6afe7cdd 48 "Non-nil if YEAR is a Hebrew calendar leap year."
4b112ac4
ER
49 (< (% (1+ (* 7 year)) 19) 7))
50
8fc9e5a0 51(defun calendar-hebrew-last-month-of-year (year)
4b112ac4 52 "The last month of the Hebrew calendar YEAR."
8fc9e5a0 53 (if (calendar-hebrew-leap-year-p year)
4b112ac4
ER
54 13
55 12))
56
8fc9e5a0 57(defun calendar-hebrew-elapsed-days (year)
6b789b4b
GM
58 "Days to mean conjunction of Tishri of Hebrew YEAR.
59Measured from Sunday before start of Hebrew calendar."
4b112ac4 60 (let* ((months-elapsed
9c68082d
GM
61 (+ (* 235 (/ (1- year) 19)) ; months in complete cycles so far
62 (* 12 (% (1- year) 19)) ; regular months in this cycle
63 (/ (1+ (* 7 (% (1- year) 19))) 19))) ; leap months this cycle
4b112ac4
ER
64 (parts-elapsed (+ 204 (* 793 (% months-elapsed 1080))))
65 (hours-elapsed (+ 5
66 (* 12 months-elapsed)
67 (* 793 (/ months-elapsed 1080))
68 (/ parts-elapsed 1080)))
71ea27ee 69 (parts ; conjunction parts
4b112ac4 70 (+ (* 1080 (% hours-elapsed 24)) (% parts-elapsed 1080)))
71ea27ee 71 (day ; conjunction day
4b112ac4
ER
72 (+ 1 (* 29 months-elapsed) (/ hours-elapsed 24)))
73 (alternative-day
9c68082d 74 (if (or (>= parts 19440) ; if the new moon is at or after midday
71ea27ee 75 (and (= (% day 7) 2) ; ...or is on a Tuesday...
9c68082d 76 (>= parts 9924) ; at 9 hours, 204 parts or later...
71ea27ee 77 ;; of a common year...
8fc9e5a0 78 (not (calendar-hebrew-leap-year-p year)))
71ea27ee 79 (and (= (% day 7) 1) ; ...or is on a Monday...
9c68082d 80 (>= parts 16789) ; at 15 hours, 589 parts or later...
71ea27ee 81 ;; at the end of a leap year.
8fc9e5a0 82 (calendar-hebrew-leap-year-p (1- year))))
71ea27ee 83 ;; Then postpone Rosh HaShanah one day.
4b112ac4 84 (1+ day)
71ea27ee 85 ;; Else:
4b112ac4 86 day)))
9c68082d
GM
87 ;; If Rosh HaShanah would occur on Sunday, Wednesday, or Friday
88 (if (memq (% alternative-day 7) (list 0 3 5))
71ea27ee 89 ;; Then postpone it one (more) day and return.
4b112ac4 90 (1+ alternative-day)
9c68082d 91 ;; Else return.
4b112ac4
ER
92 alternative-day)))
93
8fc9e5a0 94(defun calendar-hebrew-days-in-year (year)
4b112ac4 95 "Number of days in Hebrew YEAR."
8fc9e5a0
GM
96 (- (calendar-hebrew-elapsed-days (1+ year))
97 (calendar-hebrew-elapsed-days year)))
4b112ac4 98
8fc9e5a0 99(defun calendar-hebrew-long-heshvan-p (year)
6afe7cdd 100 "Non-nil if Heshvan is long in Hebrew YEAR."
8fc9e5a0 101 (= (% (calendar-hebrew-days-in-year year) 10) 5))
4b112ac4 102
8fc9e5a0 103(defun calendar-hebrew-short-kislev-p (year)
6afe7cdd 104 "Non-nil if Kislev is short in Hebrew YEAR."
8fc9e5a0 105 (= (% (calendar-hebrew-days-in-year year) 10) 3))
4b112ac4 106
8fc9e5a0 107(defun calendar-hebrew-last-day-of-month (month year)
da3fc020
GM
108 "The last day of MONTH in YEAR."
109 (if (or (memq month (list 2 4 6 10 13))
8fc9e5a0
GM
110 (and (= month 12) (not (calendar-hebrew-leap-year-p year)))
111 (and (= month 8) (not (calendar-hebrew-long-heshvan-p year)))
112 (and (= month 9) (calendar-hebrew-short-kislev-p year)))
da3fc020
GM
113 29
114 30))
115
8fc9e5a0 116(defun calendar-hebrew-to-absolute (date)
4b112ac4
ER
117 "Absolute date of Hebrew DATE.
118The absolute date is the number of days elapsed since the (imaginary)
119Gregorian date Sunday, December 31, 1 BC."
e803eab7
GM
120 (let ((month (calendar-extract-month date))
121 (day (calendar-extract-day date))
122 (year (calendar-extract-year date)))
71ea27ee
GM
123 (+ day ; days so far this month
124 (if (< month 7) ; before Tishri
125 ;; Then add days in prior months this year before and after Nisan.
4b112ac4 126 (+ (calendar-sum
8fc9e5a0
GM
127 m 7 (<= m (calendar-hebrew-last-month-of-year year))
128 (calendar-hebrew-last-day-of-month m year))
4b112ac4
ER
129 (calendar-sum
130 m 1 (< m month)
8fc9e5a0 131 (calendar-hebrew-last-day-of-month m year)))
71ea27ee 132 ;; Else add days in prior months this year.
4b112ac4
ER
133 (calendar-sum
134 m 7 (< m month)
8fc9e5a0
GM
135 (calendar-hebrew-last-day-of-month m year)))
136 (calendar-hebrew-elapsed-days year) ; days in prior years
71ea27ee 137 -1373429))) ; days elapsed before absolute date 1
4b112ac4 138
8fc9e5a0
GM
139(define-obsolete-function-alias 'calendar-absolute-from-hebrew
140 'calendar-hebrew-to-absolute "23.1")
141
da3fc020
GM
142(defun calendar-hebrew-from-absolute (date)
143 "Compute the Hebrew date (month day year) corresponding to absolute DATE.
144The absolute date is the number of days elapsed since the (imaginary)
145Gregorian date Sunday, December 31, 1 BC."
146 (let* ((greg-date (calendar-gregorian-from-absolute date))
e803eab7 147 (year (+ 3760 (calendar-extract-year greg-date)))
da3fc020 148 (month (aref [9 10 11 12 1 2 3 4 7 7 7 8]
e803eab7 149 (1- (calendar-extract-month greg-date))))
6b789b4b 150 (length (progn
8fc9e5a0 151 (while (>= date (calendar-hebrew-to-absolute
6b789b4b
GM
152 (list 7 1 (1+ year))))
153 (setq year (1+ year)))
8fc9e5a0 154 (calendar-hebrew-last-month-of-year year)))
28c02796 155 day)
6b789b4b 156 (while (> date
8fc9e5a0 157 (calendar-hebrew-to-absolute
6b789b4b 158 (list month
8fc9e5a0 159 (calendar-hebrew-last-day-of-month month year)
6b789b4b
GM
160 year)))
161 (setq month (1+ (% month length))))
da3fc020 162 (setq day (1+
8fc9e5a0 163 (- date (calendar-hebrew-to-absolute (list month 1 year)))))
da3fc020
GM
164 (list month day year)))
165
711d00e7 166(defconst calendar-hebrew-month-name-array-common-year
4b112ac4 167 ["Nisan" "Iyar" "Sivan" "Tammuz" "Av" "Elul" "Tishri"
da3fc020 168 "Heshvan" "Kislev" "Teveth" "Shevat" "Adar"]
71ea27ee 169 "Array of strings giving the names of the Hebrew months in a common year.")
4b112ac4 170
711d00e7 171(defconst calendar-hebrew-month-name-array-leap-year
4b112ac4 172 ["Nisan" "Iyar" "Sivan" "Tammuz" "Av" "Elul" "Tishri"
da3fc020 173 "Heshvan" "Kislev" "Teveth" "Shevat" "Adar I" "Adar II"]
71ea27ee 174 "Array of strings giving the names of the Hebrew months in a leap year.")
4b112ac4 175
28b3c0f5 176;;;###cal-autoload
4b112ac4
ER
177(defun calendar-hebrew-date-string (&optional date)
178 "String of Hebrew date before sunset of Gregorian DATE.
179Defaults to today's date if DATE is not given.
180Driven by the variable `calendar-date-display-form'."
181 (let* ((hebrew-date (calendar-hebrew-from-absolute
182 (calendar-absolute-from-gregorian
183 (or date (calendar-current-date)))))
184 (calendar-month-name-array
e803eab7 185 (if (calendar-hebrew-leap-year-p (calendar-extract-year hebrew-date))
4b112ac4
ER
186 calendar-hebrew-month-name-array-leap-year
187 calendar-hebrew-month-name-array-common-year)))
188 (calendar-date-string hebrew-date nil t)))
189
28b3c0f5 190;;;###cal-autoload
8fc9e5a0 191(defun calendar-hebrew-print-date ()
4b112ac4
ER
192 "Show the Hebrew calendar equivalent of the date under the cursor."
193 (interactive)
194 (message "Hebrew date (until sunset): %s"
195 (calendar-hebrew-date-string (calendar-cursor-to-date t))))
196
8fc9e5a0
GM
197(define-obsolete-function-alias 'calendar-print-hebrew-date
198 'calendar-hebrew-print-date "23.1")
199
200(defun calendar-hebrew-yahrzeit (death-date year)
4b112ac4 201 "Absolute date of the anniversary of Hebrew DEATH-DATE in Hebrew YEAR."
e803eab7
GM
202 (let ((death-day (calendar-extract-day death-date))
203 (death-month (calendar-extract-month death-date))
204 (death-year (calendar-extract-year death-date)))
4b112ac4
ER
205 (cond
206 ;; If it's Heshvan 30 it depends on the first anniversary; if
207 ;; that was not Heshvan 30, use the day before Kislev 1.
208 ((and (= death-month 8)
209 (= death-day 30)
8fc9e5a0
GM
210 (not (calendar-hebrew-long-heshvan-p (1+ death-year))))
211 (1- (calendar-hebrew-to-absolute (list 9 1 year))))
9c68082d
GM
212 ;; If it's Kislev 30 it depends on the first anniversary; if that
213 ;; was not Kislev 30, use the day before Teveth 1.
4b112ac4
ER
214 ((and (= death-month 9)
215 (= death-day 30)
8fc9e5a0
GM
216 (calendar-hebrew-short-kislev-p (1+ death-year)))
217 (1- (calendar-hebrew-to-absolute (list 10 1 year))))
9c68082d
GM
218 ;; If it's Adar II, use the same day in last month of year (Adar
219 ;; or Adar II).
4b112ac4 220 ((= death-month 13)
8fc9e5a0
GM
221 (calendar-hebrew-to-absolute
222 (list (calendar-hebrew-last-month-of-year year) death-day year)))
9c68082d
GM
223 ;; If it's the 30th in Adar I and year is not a leap year (so
224 ;; Adar has only 29 days), use the last day in Shevat.
4b112ac4
ER
225 ((and (= death-day 30)
226 (= death-month 12)
8fc9e5a0
GM
227 (not (calendar-hebrew-leap-year-p year)))
228 (calendar-hebrew-to-absolute (list 11 30 year)))
4b112ac4 229 ;; In all other cases, use the normal anniversary of the date of death.
8fc9e5a0 230 (t (calendar-hebrew-to-absolute
4b112ac4
ER
231 (list death-month death-day year))))))
232
8fc9e5a0
GM
233(define-obsolete-function-alias 'hebrew-calendar-yahrzeit
234 'calendar-hebrew-yahrzeit "23.1")
235
42281b7b
GM
236(defun calendar-hebrew-read-date ()
237 "Interactively read the arguments for a Hebrew date command.
238Reads a year, month, and day."
28c02796
GM
239 (let* ((today (calendar-current-date))
240 (year (calendar-read
241 "Hebrew calendar year (>3760): "
242 (lambda (x) (> x 3760))
d92bcf94 243 (number-to-string
e803eab7 244 (calendar-extract-year
28c02796
GM
245 (calendar-hebrew-from-absolute
246 (calendar-absolute-from-gregorian today))))))
8fc9e5a0 247 (month-array (if (calendar-hebrew-leap-year-p year)
28c02796
GM
248 calendar-hebrew-month-name-array-leap-year
249 calendar-hebrew-month-name-array-common-year))
250 (completion-ignore-case t)
251 (month (cdr (assoc-string
252 (completing-read
253 "Hebrew calendar month name: "
254 (mapcar 'list (append month-array nil))
255 (if (= year 3761)
256 (lambda (x)
257 (let ((m (cdr
258 (assoc-string
259 (car x)
260 (calendar-make-alist month-array)
261 t))))
262 (< 0
8fc9e5a0 263 (calendar-hebrew-to-absolute
28c02796 264 (list m
8fc9e5a0 265 (calendar-hebrew-last-day-of-month
28c02796
GM
266 m year)
267 year))))))
268 t)
269 (calendar-make-alist month-array 1) t)))
8fc9e5a0 270 (last (calendar-hebrew-last-day-of-month month year))
28c02796
GM
271 (first (if (and (= year 3761) (= month 10))
272 18 1))
273 (day (calendar-read
274 (format "Hebrew calendar day (%d-%d): "
275 first last)
276 (lambda (x) (and (<= first x) (<= x last))))))
277 (list (list month day year))))
278
28b3c0f5 279;;;###cal-autoload
8fc9e5a0 280(defun calendar-hebrew-goto-date (date &optional noecho)
8f11970d 281 "Move cursor to Hebrew DATE; echo Hebrew date unless NOECHO is non-nil."
42281b7b 282 (interactive (calendar-hebrew-read-date))
4b112ac4 283 (calendar-goto-date (calendar-gregorian-from-absolute
8fc9e5a0
GM
284 (calendar-hebrew-to-absolute date)))
285 (or noecho (calendar-hebrew-print-date)))
286
287(define-obsolete-function-alias 'calendar-goto-hebrew-date
288 'calendar-hebrew-goto-date "23.1")
4b112ac4 289
e803eab7 290(defvar displayed-month) ; from calendar-generate
8f11970d 291
6b789b4b
GM
292(defun calendar-hebrew-date-is-visible-p (month day)
293 "Return non-nil if Hebrew MONTH DAY is visible in the calendar window.
294Returns the corresponding Gregorian date."
9c68082d
GM
295 ;; This test is only to speed things up a bit; it works fine without it.
296 (if (memq displayed-month
1d2a9d53
GM
297 ;; What this is doing is equivalent to +1,2,3,4,5 modulo 12, ie:
298 ;; (mapcar (lambda (n) (let ((x (mod n 12)))
299 ;; (if (zerop x) 12
300 ;; x)))
301 ;; (number-sequence (1+ month) (+ 5 month)))
302 ;; Ie it makes a list:
303 ;; 2 3 4 5 6 when month = 1
304 ;; 3 4 5 6 7 when month = 2
305 ;; ...
306 ;; 8 9 10 11 12 when month = 7
307 ;; 9 10 11 12 1 when month = 8
308 ;; ...
309 ;; 12 1 2 3 4 when month = 11
310 ;; 1 2 3 4 5 when month = 12
311 ;; This implies that hebrew month N cannot occur outside
312 ;; Gregorian months N:N+6 (the calendar shows
313 ;; displayed-month +/- 1 at any time).
314 ;; So to put it another way:
315 ;; (calendar-interval month 1 displayed-month
316 ;; (if (> month displayed-month) 2 1))
317 ;; must be >= 1 and <= 5. This could be expanded to:
318 ;; (if (> month displayed-month) (+ 12 (- displayed-month month))
319 ;; (- displayed-month month)
9c68082d 320 (list
4b112ac4
ER
321 (if (< 11 month) (- month 11) (+ month 1))
322 (if (< 10 month) (- month 10) (+ month 2))
323 (if (< 9 month) (- month 9) (+ month 3))
324 (if (< 8 month) (- month 8) (+ month 4))
325 (if (< 7 month) (- month 7) (+ month 5))))
2f264ff6 326 (calendar-nongregorian-visible-p
8fc9e5a0 327 month day 'calendar-hebrew-to-absolute
2f264ff6
GM
328 'calendar-hebrew-from-absolute
329 ;; Hebrew new year is start of month 7.
330 ;; If hmonth >= 7, choose the higher year.
331 (lambda (m) (> m 6)))))
6b789b4b
GM
332
333;;;###holiday-autoload
334(defun holiday-hebrew (month day string)
335 "Holiday on MONTH, DAY (Hebrew) called STRING.
336If MONTH, DAY (Hebrew) is visible, the value returned is corresponding
337Gregorian date in the form of the list (((month day year) STRING)). Returns
338nil if it is not visible in the current calendar window."
339 (let ((gdate (calendar-hebrew-date-is-visible-p month day)))
340 (if gdate (list (list gdate string)))))
4b112ac4 341
e475d400
GM
342;; h-r-h-e should be called from holidays code.
343(declare-function holiday-filter-visible-calendar "holidays" (l))
344
2f264ff6
GM
345(defvar displayed-year)
346
28b3c0f5 347;;;###holiday-autoload
8fc9e5a0 348(defun holiday-hebrew-rosh-hashanah (&optional all)
f2268dc0 349 "List of dates related to Rosh Hashanah, as visible in calendar window.
1c76c939 350Shows only the major holidays, unless `calendar-hebrew-all-holidays-flag'
f2268dc0
GM
351or ALL is non-nil."
352 (when (memq displayed-month '(8 9 10 11))
8fc9e5a0 353 (let ((abs-r-h (calendar-hebrew-to-absolute
f2268dc0
GM
354 (list 7 1 (+ displayed-year 3761)))))
355 (holiday-filter-visible-calendar
356 (append
357 (list
358 (list (calendar-gregorian-from-absolute abs-r-h)
359 (format "Rosh HaShanah %d" (+ 3761 displayed-year)))
360 (list (calendar-gregorian-from-absolute (+ abs-r-h 9))
361 "Yom Kippur")
362 (list (calendar-gregorian-from-absolute (+ abs-r-h 14))
363 "Sukkot")
364 (list (calendar-gregorian-from-absolute (+ abs-r-h 21))
365 "Shemini Atzeret")
366 (list (calendar-gregorian-from-absolute (+ abs-r-h 22))
367 "Simchat Torah"))
1c76c939 368 (when (or all calendar-hebrew-all-holidays-flag)
f2268dc0
GM
369 (list
370 (list (calendar-gregorian-from-absolute
371 (calendar-dayname-on-or-before 6 (- abs-r-h 4)))
372 "Selichot (night)")
373 (list (calendar-gregorian-from-absolute (1- abs-r-h))
374 "Erev Rosh HaShanah")
375 (list (calendar-gregorian-from-absolute (1+ abs-r-h))
376 "Rosh HaShanah (second day)")
377 (list (calendar-gregorian-from-absolute
85d50db7 378 (+ abs-r-h (if (= (% abs-r-h 7) 4) 3 2)))
f2268dc0
GM
379 "Tzom Gedaliah")
380 (list (calendar-gregorian-from-absolute
381 (calendar-dayname-on-or-before 6 (+ 7 abs-r-h)))
382 "Shabbat Shuvah")
383 (list (calendar-gregorian-from-absolute (+ abs-r-h 8))
384 "Erev Yom Kippur")
385 (list (calendar-gregorian-from-absolute (+ abs-r-h 13))
386 "Erev Sukkot")
387 (list (calendar-gregorian-from-absolute (+ abs-r-h 15))
388 "Sukkot (second day)")
389 (list (calendar-gregorian-from-absolute (+ abs-r-h 16))
390 "Hol Hamoed Sukkot (first day)")
391 (list (calendar-gregorian-from-absolute (+ abs-r-h 17))
392 "Hol Hamoed Sukkot (second day)")
393 (list (calendar-gregorian-from-absolute (+ abs-r-h 18))
394 "Hol Hamoed Sukkot (third day)")
395 (list (calendar-gregorian-from-absolute (+ abs-r-h 19))
396 "Hol Hamoed Sukkot (fourth day)")
397 (list (calendar-gregorian-from-absolute (+ abs-r-h 20))
398 "Hoshanah Rabbah"))))))))
4b112ac4 399
28b3c0f5 400;;;###holiday-autoload
8fc9e5a0
GM
401(define-obsolete-function-alias 'holiday-rosh-hashanah-etc
402 'holiday-hebrew-rosh-hashanah "23.1")
403
404;;;###holiday-autoload
405(defun holiday-hebrew-hanukkah (&optional all)
f2268dc0 406 "List of dates related to Hanukkah, as visible in calendar window.
1c76c939 407Shows only Hanukkah, unless `calendar-hebrew-all-holidays-flag' or ALL
f2268dc0 408is non-nil."
9c68082d 409 ;; This test is only to speed things up a bit, it works fine without it.
f2268dc0
GM
410 (when (memq displayed-month '(10 11 12 1 2))
411 (let* ((m displayed-month)
412 (y displayed-year)
413 (h-y (progn
e803eab7
GM
414 (calendar-increment-month m y 1)
415 (calendar-extract-year
f2268dc0
GM
416 (calendar-hebrew-from-absolute
417 (calendar-absolute-from-gregorian
418 (list m (calendar-last-day-of-month m y) y))))))
8fc9e5a0 419 (abs-h (calendar-hebrew-to-absolute (list 9 25 h-y)))
f2268dc0
GM
420 (ord ["first" "second" "third" "fourth" "fifth" "sixth"
421 "seventh" "eighth"])
422 han)
423 (holiday-filter-visible-calendar
1c76c939 424 (if (or all calendar-hebrew-all-holidays-flag)
f2268dc0
GM
425 (append
426 (list
427 (list (calendar-gregorian-from-absolute (1- abs-h))
428 "Erev Hanukkah"))
429 (dotimes (i 8 (nreverse han))
430 (push (list
431 (calendar-gregorian-from-absolute (+ abs-h i))
432 (format "Hanukkah (%s day)" (aref ord i)))
433 han)))
434 (list (list (calendar-gregorian-from-absolute abs-h) "Hanukkah")))))))
4b112ac4 435
28b3c0f5 436;;;###holiday-autoload
8fc9e5a0
GM
437(define-obsolete-function-alias 'holiday-hanukkah
438 'holiday-hebrew-hanukkah "23.1")
439
440;;;###holiday-autoload
441(defun holiday-hebrew-passover (&optional all)
f2268dc0 442 "List of dates related to Passover, as visible in calendar window.
1c76c939 443Shows only the major holidays, unless `calendar-hebrew-all-holidays-flag'
f2268dc0
GM
444or ALL is non-nil."
445 (when (< displayed-month 8)
8fc9e5a0 446 (let ((abs-p (calendar-hebrew-to-absolute
f2268dc0
GM
447 (list 1 15 (+ displayed-year 3760)))))
448 (holiday-filter-visible-calendar
449 ;; The first two are out of order when the others are added.
450 (append
451 (list
452 (list (calendar-gregorian-from-absolute abs-p) "Passover")
453 (list (calendar-gregorian-from-absolute (+ abs-p 50))
454 "Shavuot"))
1c76c939 455 (when (or all calendar-hebrew-all-holidays-flag)
85d50db7
GM
456 (let ((wday (% abs-p 7)))
457 (list
458 (list (calendar-gregorian-from-absolute
459 (calendar-dayname-on-or-before 6 (- abs-p 43)))
460 "Shabbat Shekalim")
461 (list (calendar-gregorian-from-absolute
462 (calendar-dayname-on-or-before 6 (- abs-p 30)))
463 "Shabbat Zachor")
464 (list (calendar-gregorian-from-absolute
465 (- abs-p (if (= wday 2) 33 31)))
466 "Fast of Esther")
467 (list (calendar-gregorian-from-absolute (- abs-p 31))
468 "Erev Purim")
469 (list (calendar-gregorian-from-absolute (- abs-p 30))
470 "Purim")
471 (list (calendar-gregorian-from-absolute
472 (- abs-p (if (zerop wday) 28 29)))
473 "Shushan Purim")
474 (list (calendar-gregorian-from-absolute
475 (- (calendar-dayname-on-or-before 6 (- abs-p 14)) 7))
476 "Shabbat Parah")
477 (list (calendar-gregorian-from-absolute
478 (calendar-dayname-on-or-before 6 (- abs-p 14)))
479 "Shabbat HaHodesh")
480 (list (calendar-gregorian-from-absolute
481 (calendar-dayname-on-or-before 6 (1- abs-p)))
482 "Shabbat HaGadol")
483 (list (calendar-gregorian-from-absolute (1- abs-p))
484 "Erev Passover")
485 (list (calendar-gregorian-from-absolute (1+ abs-p))
486 "Passover (second day)")
487 (list (calendar-gregorian-from-absolute (+ abs-p 2))
488 "Hol Hamoed Passover (first day)")
489 (list (calendar-gregorian-from-absolute (+ abs-p 3))
490 "Hol Hamoed Passover (second day)")
491 (list (calendar-gregorian-from-absolute (+ abs-p 4))
492 "Hol Hamoed Passover (third day)")
493 (list (calendar-gregorian-from-absolute (+ abs-p 5))
494 "Hol Hamoed Passover (fourth day)")
495 (list (calendar-gregorian-from-absolute (+ abs-p 6))
496 "Passover (seventh day)")
497 (list (calendar-gregorian-from-absolute (+ abs-p 7))
498 "Passover (eighth day)")
499 (list (calendar-gregorian-from-absolute
500 (+ abs-p (if (zerop (% (+ abs-p 12) 7))
501 13
502 12)))
503 "Yom HaShoah")
504 (list (calendar-gregorian-from-absolute
505 (+ abs-p
506 ;; If falls on Sat or Fri, moves to preceding Thurs.
507 ;; If falls on Mon, moves to Tues (since 2004).
508 (cond ((zerop wday) 18) ; Sat
509 ((= wday 6) 19) ; Fri
510 ((= wday 2) 21) ; Mon
511 (t 20))))
512 "Yom HaAtzma'ut")
513 (list (calendar-gregorian-from-absolute (+ abs-p 33))
514 "Lag BaOmer")
515 (list (calendar-gregorian-from-absolute (+ abs-p 43))
516 "Yom Yerushalaim")
517 (list (calendar-gregorian-from-absolute (+ abs-p 49))
518 "Erev Shavuot")
519 (list (calendar-gregorian-from-absolute (+ abs-p 51))
520 "Shavuot (second day)")))))))))
4b112ac4 521
28b3c0f5 522;;;###holiday-autoload
8fc9e5a0
GM
523(define-obsolete-function-alias 'holiday-passover-etc
524 'holiday-hebrew-passover "23.1")
525
526;;;###holiday-autoload
527(defun holiday-hebrew-tisha-b-av ()
4b112ac4 528 "List of dates around Tisha B'Av, as visible in calendar window."
f2268dc0 529 (when (memq displayed-month '(5 6 7 8 9))
85d50db7
GM
530 (let* ((abs-t-a (calendar-hebrew-to-absolute
531 (list 5 9 (+ displayed-year 3760))))
532 (wday (% abs-t-a 7)))
8705f7f3 533 (holiday-filter-visible-calendar
a1506d29 534 (list
4b112ac4 535 (list (calendar-gregorian-from-absolute
85d50db7 536 (- abs-t-a (if (= wday 6) 20 21)))
4b112ac4
ER
537 "Tzom Tammuz")
538 (list (calendar-gregorian-from-absolute
539 (calendar-dayname-on-or-before 6 abs-t-a))
540 "Shabbat Hazon")
541 (list (calendar-gregorian-from-absolute
85d50db7 542 (if (= wday 6) (1+ abs-t-a) abs-t-a))
4b112ac4
ER
543 "Tisha B'Av")
544 (list (calendar-gregorian-from-absolute
545 (calendar-dayname-on-or-before 6 (+ abs-t-a 7)))
546 "Shabbat Nahamu"))))))
547
8fc9e5a0
GM
548;;;###holiday-autoload
549(define-obsolete-function-alias 'holiday-tisha-b-av-etc
550 'holiday-hebrew-tisha-b-av "23.1")
551
f2268dc0
GM
552(autoload 'holiday-julian "cal-julian")
553
554;;;###holiday-autoload
555(defun holiday-hebrew-misc ()
556 "Miscellaneous Hebrew holidays, if visible in calendar window.
557Includes: Tal Umatar, Tzom Teveth, Tu B'Shevat, Shabbat Shirah, and
558Kiddush HaHamah."
559 (let ((m displayed-month)
560 (y displayed-year)
85d50db7 561 year h-year)
f2268dc0
GM
562 (append
563 (holiday-julian
564 11
565 (progn
e803eab7
GM
566 (calendar-increment-month m y -1)
567 (setq year (calendar-extract-year
f2268dc0
GM
568 (calendar-julian-from-absolute
569 (calendar-absolute-from-gregorian (list m 1 y)))))
570 (if (zerop (% (1+ year) 4))
571 22
572 21)) "\"Tal Umatar\" (evening)")
573 (holiday-hebrew
574 10
575 (progn
e803eab7 576 (setq h-year (calendar-extract-year
f2268dc0
GM
577 (calendar-hebrew-from-absolute
578 (calendar-absolute-from-gregorian
579 (list displayed-month 28 displayed-year)))))
8fc9e5a0 580 (if (= 6 (% (calendar-hebrew-to-absolute (list 10 10 h-year))
f2268dc0
GM
581 7))
582 11 10))
583 "Tzom Teveth")
584 (holiday-hebrew 11 15 "Tu B'Shevat")
585 (holiday-hebrew
586 11
587 (progn
588 (setq m displayed-month
589 y displayed-year
590 h-year (progn
e803eab7
GM
591 (calendar-increment-month m y 1)
592 (calendar-extract-year
f2268dc0
GM
593 (calendar-hebrew-from-absolute
594 (calendar-absolute-from-gregorian
85d50db7
GM
595 (list m (calendar-last-day-of-month m y) y))))))
596 (calendar-extract-day
597 (calendar-hebrew-from-absolute
598 (calendar-dayname-on-or-before
599 6 (calendar-hebrew-to-absolute
600 (list 11
601 (if (= 6
602 (% (calendar-hebrew-to-absolute
603 (list 7 1 h-year))
604 7))
605 17 16) h-year))))))
f2268dc0
GM
606 "Shabbat Shirah")
607 (and (progn
608 (setq m displayed-month
609 y displayed-year
610 year (progn
e803eab7
GM
611 (calendar-increment-month m y -1)
612 (calendar-extract-year
f2268dc0
GM
613 (calendar-julian-from-absolute
614 (calendar-absolute-from-gregorian (list m 1 y))))))
615 (= 21 (% year 28)))
616 (holiday-julian 3 26 "Kiddush HaHamah")))))
617
618
711d00e7 619(autoload 'diary-list-entries-1 "diary-lib")
c3efd659 620
28b3c0f5 621;;;###diary-autoload
8fc9e5a0 622(defun diary-hebrew-list-entries ()
4b112ac4 623 "Add any Hebrew date entries from the diary file to `diary-entries-list'.
0e96e25f 624Hebrew date diary entries must be prefaced by `diary-hebrew-entry-symbol'
8f11970d
GM
625\(normally an `H'). The same diary date forms govern the style
626of the Hebrew calendar entries, except that the Hebrew month
872edde5 627names cannot be abbreviated. The Hebrew months are numbered
8f11970d
GM
628from 1 to 13 with Nisan being 1, 12 being Adar I and 13 being
629Adar II; you must use `Adar I' if you want Adar of a common
630Hebrew year. If a Hebrew date diary entry begins with
631`diary-nonmarking-symbol', the entry will appear in the diary
632listing, but will not be marked in the calendar. This function
9ee4e581 633is provided for use with `diary-nongregorian-listing-hook'."
711d00e7 634 (diary-list-entries-1 calendar-hebrew-month-name-array-leap-year
0e96e25f 635 diary-hebrew-entry-symbol
711d00e7 636 'calendar-hebrew-from-absolute))
8fc9e5a0
GM
637;;;###diary-autoload
638(define-obsolete-function-alias 'list-hebrew-diary-entries
639 'diary-hebrew-list-entries "23.1")
4b112ac4 640
28c02796
GM
641(autoload 'calendar-mark-complex "diary-lib")
642
28b3c0f5 643;;;###diary-autoload
8fc9e5a0 644(defun calendar-hebrew-mark-date-pattern (month day year &optional color)
da3fc020 645 "Mark dates in calendar window that conform to Hebrew date MONTH/DAY/YEAR.
28c02796 646A value of 0 in any position is a wildcard. Optional argument COLOR is
e803eab7 647passed to `calendar-mark-visible-date' as MARK."
28c02796
GM
648 ;; FIXME not the same as the Bahai and Islamic cases, so can't use
649 ;; calendar-mark-1.
937e6a56 650 (with-current-buffer calendar-buffer
0d1bb2ff
GM
651 (if (and (not (zerop month)) (not (zerop day)))
652 (if (not (zerop year))
da3fc020
GM
653 ;; Fully specified Hebrew date.
654 (let ((date (calendar-gregorian-from-absolute
8fc9e5a0 655 (calendar-hebrew-to-absolute
da3fc020
GM
656 (list month day year)))))
657 (if (calendar-date-is-visible-p date)
e803eab7 658 (calendar-mark-visible-date date color)))
6b789b4b
GM
659 ;; Month and day in any year.
660 (let ((gdate (calendar-hebrew-date-is-visible-p month day)))
e803eab7 661 (if gdate (calendar-mark-visible-date gdate color))))
28c02796
GM
662 (calendar-mark-complex month day year
663 'calendar-hebrew-from-absolute color))))
da3fc020 664
8fc9e5a0
GM
665;;;###diary-autoload
666(define-obsolete-function-alias 'mark-hebrew-calendar-date-pattern
667 'calendar-hebrew-mark-date-pattern "23.1")
668
711d00e7 669(autoload 'diary-mark-entries-1 "diary-lib")
e475d400 670
28b3c0f5 671;;;###diary-autoload
8fc9e5a0 672(defun diary-hebrew-mark-entries ()
4b112ac4 673 "Mark days in the calendar window that have Hebrew date diary entries.
711d00e7
GM
674Marks each entry in `diary-file' (or included files) visible in the calendar
675window. See `list-hebrew-diary-entries' for more information."
8fc9e5a0 676 (diary-mark-entries-1 'calendar-hebrew-mark-date-pattern
618c03c1 677 calendar-hebrew-month-name-array-leap-year
0e96e25f 678 diary-hebrew-entry-symbol
618c03c1 679 'calendar-hebrew-from-absolute))
4b112ac4 680
8fc9e5a0
GM
681;;;###diary-autoload
682(define-obsolete-function-alias 'mark-hebrew-diary-entries
683 'diary-hebrew-mark-entries "23.1")
f2b46435
GM
684
685(autoload 'diary-insert-entry-1 "diary-lib")
686
28b3c0f5 687;;;###cal-autoload
8fc9e5a0
GM
688(defun diary-hebrew-insert-entry (arg)
689 "Insert a diary entry for the Hebrew date at point.
6afe7cdd 690Prefix argument ARG makes the entry nonmarking."
4b112ac4 691 (interactive "P")
f2b46435 692 (diary-insert-entry-1 nil arg calendar-hebrew-month-name-array-leap-year
0e96e25f 693 diary-hebrew-entry-symbol
f2b46435 694 'calendar-hebrew-from-absolute))
4b112ac4 695
8fc9e5a0
GM
696;;;###diary-autoload
697(define-obsolete-function-alias 'insert-hebrew-diary-entry
698 'diary-hebrew-insert-entry "23.1")
699
28b3c0f5 700;;;###cal-autoload
8fc9e5a0 701(defun diary-hebrew-insert-monthly-entry (arg)
4b112ac4
ER
702 "Insert a monthly diary entry.
703For the day of the Hebrew month corresponding to the date indicated by point.
6afe7cdd 704Prefix argument ARG makes the entry nonmarking."
4b112ac4 705 (interactive "P")
f2b46435 706 (diary-insert-entry-1 'monthly arg calendar-hebrew-month-name-array-leap-year
0e96e25f 707 diary-hebrew-entry-symbol
f2b46435 708 'calendar-hebrew-from-absolute))
8fc9e5a0
GM
709;;;###diary-autoload
710(define-obsolete-function-alias 'insert-monthly-hebrew-diary-entry
711 'diary-hebrew-insert-monthly-entry "23.1")
4b112ac4 712
28b3c0f5 713;;;###cal-autoload
8fc9e5a0 714(defun diary-hebrew-insert-yearly-entry (arg)
4b112ac4
ER
715 "Insert an annual diary entry.
716For the day of the Hebrew year corresponding to the date indicated by point.
6afe7cdd 717Prefix argument ARG makes the entry nonmarking."
4b112ac4 718 (interactive "P")
f2b46435 719 (diary-insert-entry-1 'yearly arg calendar-hebrew-month-name-array-leap-year
0e96e25f 720 diary-hebrew-entry-symbol
f2b46435 721 'calendar-hebrew-from-absolute))
8fc9e5a0
GM
722;;;###diary-autoload
723(define-obsolete-function-alias 'insert-yearly-hebrew-diary-entry
724 'diary-hebrew-insert-yearly-entry "23.1")
4b112ac4
ER
725
726;;;###autoload
4e740fd0 727(defun calendar-hebrew-list-yahrzeits (death-date start-year end-year)
4b112ac4
ER
728 "List Yahrzeit dates for *Gregorian* DEATH-DATE from START-YEAR to END-YEAR.
729When called interactively from the calendar window, the date of death is taken
730from the cursor position."
731 (interactive
732 (let* ((death-date
733 (if (equal (current-buffer) (get-buffer calendar-buffer))
d68cd087 734 (calendar-cursor-to-date t)
4b112ac4
ER
735 (let* ((today (calendar-current-date))
736 (year (calendar-read
737 "Year of death (>0): "
c645b7bb 738 (lambda (x) (> x 0))
d92bcf94 739 (number-to-string (calendar-extract-year today))))
4b112ac4
ER
740 (month-array calendar-month-name-array)
741 (completion-ignore-case t)
abe4091c 742 (month (cdr (assoc-string
bf7b2caf
RS
743 (completing-read
744 "Month of death (name): "
745 (mapcar 'list (append month-array nil))
746 nil t)
abe4091c 747 (calendar-make-alist month-array 1) t)))
4b112ac4
ER
748 (last (calendar-last-day-of-month month year))
749 (day (calendar-read
750 (format "Day of death (1-%d): " last)
c645b7bb 751 (lambda (x) (and (< 0 x) (<= x last))))))
4b112ac4 752 (list month day year))))
e803eab7 753 (death-year (calendar-extract-year death-date))
4b112ac4
ER
754 (start-year (calendar-read
755 (format "Starting year of Yahrzeit table (>%d): "
756 death-year)
c645b7bb 757 (lambda (x) (> x death-year))
d92bcf94 758 (number-to-string (1+ death-year))))
4b112ac4
ER
759 (end-year (calendar-read
760 (format "Ending year of Yahrzeit table (>=%d): "
761 start-year)
71ea27ee
GM
762 (lambda (x) (>= x start-year)))))
763 (list death-date start-year end-year)))
6afe7cdd 764 (message "Computing Yahrzeits...")
66471e03 765 (let* ((h-date (calendar-hebrew-from-absolute
4b112ac4 766 (calendar-absolute-from-gregorian death-date)))
e803eab7 767 (h-year (calendar-extract-year h-date))
2d354894 768 (i (1- start-year)))
e803eab7 769 (calendar-in-read-only-buffer calendar-hebrew-yahrzeit-buffer
318a5488
GM
770 (calendar-set-mode-line
771 (format "Yahrzeit dates for %s = %s"
772 (calendar-date-string death-date)
773 (let ((calendar-month-name-array
8fc9e5a0 774 (if (calendar-hebrew-leap-year-p h-year)
318a5488
GM
775 calendar-hebrew-month-name-array-leap-year
776 calendar-hebrew-month-name-array-common-year)))
777 (calendar-date-string h-date nil t))))
2d354894 778 (while (<= (setq i (1+ i)) end-year)
318a5488
GM
779 (insert
780 (calendar-date-string
781 (calendar-gregorian-from-absolute
8fc9e5a0 782 (calendar-hebrew-yahrzeit
318a5488 783 h-date
e803eab7 784 (calendar-extract-year
318a5488 785 (calendar-hebrew-from-absolute
2d354894
GM
786 (calendar-absolute-from-gregorian (list 1 1 i))))))) "\n"))))
787 (message "Computing Yahrzeits...done"))
4b112ac4 788
8fc9e5a0
GM
789;;;###autoload
790(define-obsolete-function-alias 'list-yahrzeit-dates
4e740fd0 791 'calendar-hebrew-list-yahrzeits "23.1")
8fc9e5a0 792
7454f200
GM
793(defun calendar-hebrew-birthday (date year)
794 "Absolute date of the anniversary of Hebrew birth DATE, in Hebrew YEAR."
795 (let ((b-day (calendar-extract-day date))
796 (b-month (calendar-extract-month date))
797 (b-year (calendar-extract-year date)))
798 ;; If it's Adar in a normal Hebrew year or Adar II in a Hebrew leap year...
799 (if (= b-month (calendar-hebrew-last-month-of-year b-year))
800 ;; ...then use the same day in last month of Hebrew year.
801 (calendar-hebrew-to-absolute
802 (list (calendar-hebrew-last-month-of-year year) b-day year))
cdcbd5a7 803 ;; Else use the normal anniversary of the birth date,
7454f200
GM
804 ;; or the corresponding day in years without that date.
805 (+ (calendar-hebrew-to-absolute (list b-month 1 year)) b-day -1))))
cdcbd5a7 806
c3efd659
GM
807(defvar date)
808
9ee4e581 809;; To be called from diary-list-sexp-entries, where DATE is bound.
28b3c0f5 810;;;###diary-autoload
4b112ac4
ER
811(defun diary-hebrew-date ()
812 "Hebrew calendar equivalent of date diary entry."
813 (format "Hebrew date (until sunset): %s" (calendar-hebrew-date-string date)))
814
7454f200 815(defvar entry)
5e7a95b0 816(declare-function diary-ordinal-suffix "diary-lib" (n))
7454f200
GM
817
818;;;###diary-autoload
819(defun diary-hebrew-birthday (month day year &optional after-sunset)
820 "Hebrew birthday diary entry.
821Entry applies if date is birthdate (MONTH DAY YEAR), or the day before.
822The order of the input parameters changes according to
823`calendar-date-style' (e.g. to DAY MONTH YEAR in the European style).
824
825Assumes the associated diary entry is the name of the person.
826
827Although the date of birth is specified by the *civil* calendar,
828this function determines the proper Hebrew calendar birthday.
829If the optional argument AFTER-SUNSET is non-nil, this means the
830birth occurred after local sunset on the given civil date.
831In this case, the following civil date corresponds to the Hebrew birthday."
cdcbd5a7
ER
832 (let* ((h-date (calendar-hebrew-from-absolute
833 (+ (calendar-absolute-from-gregorian
7454f200 834 (diary-make-date month day year))
cdcbd5a7 835 (if after-sunset 1 0))))
7454f200
GM
836 (h-year (calendar-extract-year h-date)) ; birth-day
837 (d (calendar-absolute-from-gregorian date)) ; today
838 (h-yr (calendar-extract-year (calendar-hebrew-from-absolute d)))
839 (age (- h-yr h-year)) ; current H year - birth H-year
840 (b-date (calendar-hebrew-birthday h-date h-yr)))
841 (and (> age 0) (memq b-date (list d (1+ d)))
842 (format "%s's %d%s Hebrew birthday%s" entry age
843 (diary-ordinal-suffix age)
844 (if (= b-date d) "" " (evening)")))))
cdcbd5a7 845
28b3c0f5 846;;;###diary-autoload
8fc9e5a0 847(defun diary-hebrew-omer (&optional mark)
4b112ac4 848 "Omer count diary entry.
9a27723c
RS
849Entry applies if date is within 50 days after Passover.
850
a1506d29 851An optional parameter MARK specifies a face or single-character string to
9a27723c 852use when highlighting the day in the calendar."
4b112ac4 853 (let* ((passover
8fc9e5a0 854 (calendar-hebrew-to-absolute
e803eab7 855 (list 1 15 (+ (calendar-extract-year date) 3760))))
4b112ac4
ER
856 (omer (- (calendar-absolute-from-gregorian date) passover))
857 (week (/ omer 7))
858 (day (% omer 7)))
859 (if (and (> omer 0) (< omer 50))
a1506d29 860 (cons mark
71ea27ee
GM
861 (format "Day %d%s of the omer (until sunset)"
862 omer
863 (if (zerop week)
864 ""
865 (format ", that is, %d week%s%s"
866 week
867 (if (= week 1) "" "s")
868 (if (zerop day)
869 ""
870 (format " and %d day%s"
871 day (if (= day 1) "" "s"))))))))))
8fc9e5a0
GM
872;;;###diary-autoload
873(define-obsolete-function-alias 'diary-omer 'diary-hebrew-omer "23.1")
4b112ac4 874
f2b46435
GM
875(autoload 'diary-make-date "diary-lib")
876
b4cb42a4
GM
877(declare-function diary-ordinal-suffix "diary-lib" (n))
878
28b3c0f5 879;;;###diary-autoload
e63e9234
ER
880(defun diary-hebrew-yahrzeit (death-month death-day death-year
881 &optional mark after-sunset)
6afe7cdd 882 "Yahrzeit diary entry--entry applies if date is Yahrzeit or the day before.
f2b46435
GM
883Parameters are DEATH-MONTH, DEATH-DAY, DEATH-YEAR; the diary
884entry is assumed to be the name of the person. Although the date
885of death is specified by the civil calendar, the proper Hebrew
886calendar Yahrzeit is determined.
887
e63e9234
ER
888If the death occurred after local sunset on the given civil date,
889the following civil date corresponds to the Hebrew date of
890death--set the optional parameter AFTER-SUNSET non-nil in this case.
891
f2b46435
GM
892The order of the input parameters changes according to `calendar-date-style'
893\(e.g. to DEATH-DAY, DEATH-MONTH, DEATH-YEAR in the European style).
9a27723c 894
a1506d29 895An optional parameter MARK specifies a face or single-character string to
9a27723c 896use when highlighting the day in the calendar."
4b112ac4 897 (let* ((h-date (calendar-hebrew-from-absolute
e63e9234
ER
898 (+ (calendar-absolute-from-gregorian
899 (diary-make-date death-month death-day death-year))
900 (if after-sunset 1 0))))
e803eab7 901 (h-year (calendar-extract-year h-date))
4b112ac4 902 (d (calendar-absolute-from-gregorian date))
e803eab7 903 (yr (calendar-extract-year (calendar-hebrew-from-absolute d)))
4b112ac4 904 (diff (- yr h-year))
8fc9e5a0 905 (y (calendar-hebrew-yahrzeit h-date yr)))
4b112ac4 906 (if (and (> diff 0) (or (= y d) (= y (1+ d))))
9a27723c 907 (cons mark
71ea27ee
GM
908 (format "Yahrzeit of %s%s: %d%s anniversary"
909 entry
910 (if (= y d) "" " (evening)")
911 diff
4980d28f
GM
912 (diary-ordinal-suffix diff))))))
913
8fc9e5a0
GM
914;;;###diary-autoload
915(define-obsolete-function-alias 'diary-yahrzeit 'diary-hebrew-yahrzeit "23.1")
4b112ac4 916
28b3c0f5 917;;;###diary-autoload
8fc9e5a0 918(defun diary-hebrew-rosh-hodesh (&optional mark)
4b112ac4 919 "Rosh Hodesh diary entry.
9a27723c
RS
920Entry applies if date is Rosh Hodesh, the day before, or the Saturday before.
921
a1506d29 922An optional parameter MARK specifies a face or single-character string to
9a27723c 923use when highlighting the day in the calendar."
4b112ac4
ER
924 (let* ((d (calendar-absolute-from-gregorian date))
925 (h-date (calendar-hebrew-from-absolute d))
e803eab7
GM
926 (h-month (calendar-extract-month h-date))
927 (h-day (calendar-extract-day h-date))
928 (h-year (calendar-extract-year h-date))
8fc9e5a0
GM
929 (leap-year (calendar-hebrew-leap-year-p h-year))
930 (last-day (calendar-hebrew-last-day-of-month h-month h-year))
4b112ac4
ER
931 (h-month-names
932 (if leap-year
933 calendar-hebrew-month-name-array-leap-year
934 calendar-hebrew-month-name-array-common-year))
935 (this-month (aref h-month-names (1- h-month)))
e803eab7 936 (h-yesterday (calendar-extract-day
4b112ac4
ER
937 (calendar-hebrew-from-absolute (1- d)))))
938 (if (or (= h-day 30) (and (= h-day 1) (/= h-month 7)))
a1506d29 939 (cons mark
71ea27ee
GM
940 (format
941 "Rosh Hodesh %s"
942 (if (= h-day 30)
943 (format
944 "%s (first day)"
945 ;; Next month must be in the same year since this
946 ;; month can't be the last month of the year since
947 ;; it has 30 days
948 (aref h-month-names h-month))
949 (if (= h-yesterday 30)
950 (format "%s (second day)" this-month)
951 this-month))))
952 (if (= (% d 7) 6) ; Saturday--check for Shabbat Mevarchim
c0749a51
GM
953 (cond ((and (> h-day 22) (/= h-month 6) (= 29 last-day))
954 (cons mark
71ea27ee
GM
955 (format "Mevarchim Rosh Hodesh %s (%s)"
956 (aref h-month-names
957 (if (= h-month
8fc9e5a0 958 (calendar-hebrew-last-month-of-year
71ea27ee
GM
959 h-year))
960 0 h-month))
c0749a51
GM
961 (aref calendar-day-name-array (- 29 h-day)))))
962 ((and (< h-day 30) (> h-day 22) (= 30 last-day))
963 (cons mark
71ea27ee
GM
964 (format "Mevarchim Rosh Hodesh %s (%s-%s)"
965 (aref h-month-names h-month)
966 (if (= h-day 29)
967 "tomorrow"
968 (aref calendar-day-name-array (- 29 h-day)))
969 (aref calendar-day-name-array
970 (% (- 30 h-day) 7))))))
4b112ac4 971 (if (and (= h-day 29) (/= h-month 6))
347a0e23 972 (cons mark
71ea27ee
GM
973 (format "Erev Rosh Hodesh %s"
974 (aref h-month-names
975 (if (= h-month
8fc9e5a0 976 (calendar-hebrew-last-month-of-year
71ea27ee
GM
977 h-year))
978 0 h-month)))))))))
8fc9e5a0
GM
979;;;###diary-autoload
980(define-obsolete-function-alias 'diary-rosh-hodesh
981 'diary-hebrew-rosh-hodesh "23.1")
9a27723c 982
8fc9e5a0 983(defconst calendar-hebrew-parashiot-names
71ea27ee
GM
984 ["Bereshith" "Noah" "Lech L'cha" "Vayera" "Hayei Sarah" "Toledoth"
985 "Vayetze" "Vayishlah" "Vayeshev" "Mikketz" "Vayiggash" "Vayhi"
986 "Shemoth" "Vaera" "Bo" "Beshallah" "Yithro" "Mishpatim"
987 "Terumah" "Tetzavveh" "Ki Tissa" "Vayakhel" "Pekudei" "Vayikra"
988 "Tzav" "Shemini" "Tazria" "Metzora" "Aharei Moth" "Kedoshim"
989 "Emor" "Behar" "Behukkotai" "Bemidbar" "Naso" "Behaalot'cha"
990 "Shelah L'cha" "Korah" "Hukkath" "Balak" "Pinhas" "Mattoth"
991 "Masei" "Devarim" "Vaethanan" "Ekev" "Reeh" "Shofetim"
992 "Ki Tetze" "Ki Tavo" "Nitzavim" "Vayelech" "Haazinu"]
da3fc020
GM
993 "The names of the parashiot in the Torah.")
994
8fc9e5a0 995(defun calendar-hebrew-parasha-name (p)
da3fc020 996 "Name(s) corresponding to parasha P."
71ea27ee 997 (if (arrayp p) ; combined parasha
da3fc020 998 (format "%s/%s"
8fc9e5a0
GM
999 (aref calendar-hebrew-parashiot-names (aref p 0))
1000 (aref calendar-hebrew-parashiot-names (aref p 1)))
1001 (aref calendar-hebrew-parashiot-names p)))
da3fc020 1002
711d00e7 1003;; Following 14 constants are used in diary-parasha (intern).
8f11970d 1004
9c68082d 1005;; The seven ordinary year types (keviot).
8fc9e5a0 1006(defconst calendar-hebrew-year-Saturday-incomplete-Sunday
4b112ac4 1007 [nil 52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21 22]
71ea27ee
GM
1008 23 24 nil 25 [26 27] [28 29] 30 [31 32] 33 34 35 36 37 38 39 40 [41 42]
1009 43 44 45 46 47 48 49 50]
4b112ac4
ER
1010 "The structure of the parashiot.
1011Hebrew year starts on Saturday, is `incomplete' (Heshvan and Kislev each have
101229 days), and has Passover start on Sunday.")
1013
8fc9e5a0 1014(defconst calendar-hebrew-year-Saturday-complete-Tuesday
4b112ac4 1015 [nil 52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21 22]
71ea27ee
GM
1016 23 24 nil 25 [26 27] [28 29] 30 [31 32] 33 34 35 36 37 38 39 40 [41 42]
1017 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1018 "The structure of the parashiot.
1019Hebrew year that starts on Saturday, is `complete' (Heshvan and Kislev each
1020have 30 days), and has Passover start on Tuesday.")
1021
8fc9e5a0 1022(defconst calendar-hebrew-year-Monday-incomplete-Tuesday
4b112ac4 1023 [51 52 nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21 22]
71ea27ee
GM
1024 23 24 nil 25 [26 27] [28 29] 30 [31 32] 33 34 35 36 37 38 39 40 [41 42]
1025 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1026 "The structure of the parashiot.
1027Hebrew year that starts on Monday, is `incomplete' (Heshvan and Kislev each
1028have 29 days), and has Passover start on Tuesday.")
1029
8fc9e5a0 1030(defconst calendar-hebrew-year-Monday-complete-Thursday
4b112ac4 1031 [51 52 nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21 22]
71ea27ee
GM
1032 23 24 nil 25 [26 27] [28 29] 30 [31 32] 33 (nil . 34) (34 . 35) (35 . 36)
1033 (36 . 37) (37 . 38) ([38 39] . 39) 40 [41 42] 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1034 "The structure of the parashiot.
1035Hebrew year that starts on Monday, is `complete' (Heshvan and Kislev each have
103630 days), and has Passover start on Thursday.")
1037
8fc9e5a0 1038(defconst calendar-hebrew-year-Tuesday-regular-Thursday
4b112ac4 1039 [51 52 nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21 22]
71ea27ee
GM
1040 23 24 nil 25 [26 27] [28 29] 30 [31 32] 33 (nil . 34) (34 . 35) (35 . 36)
1041 (36 . 37) (37 . 38) ([38 39] . 39) 40 [41 42] 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1042 "The structure of the parashiot.
1043Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29 days and
1044Kislev has 30 days), and has Passover start on Thursday.")
1045
8fc9e5a0 1046(defconst calendar-hebrew-year-Thursday-regular-Saturday
4b112ac4 1047 [52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21 22] 23
71ea27ee
GM
1048 24 nil (nil . 25) (25 . [26 27]) ([26 27] . [28 29]) ([28 29] . 30)
1049 (30 . 31) ([31 32] . 32) 33 34 35 36 37 38 39 40 [41 42] 43 44 45 46 47 48
1050 49 50]
4b112ac4
ER
1051 "The structure of the parashiot.
1052Hebrew year that starts on Thursday, is `regular' (Heshvan has 29 days and
1053Kislev has 30 days), and has Passover start on Saturday.")
1054
8fc9e5a0 1055(defconst calendar-hebrew-year-Thursday-complete-Sunday
4b112ac4 1056 [52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1057 23 24 nil 25 [26 27] [28 29] 30 [31 32] 33 34 35 36 37 38 39 40 [41 42]
1058 43 44 45 46 47 48 49 50]
4b112ac4
ER
1059 "The structure of the parashiot.
1060Hebrew year that starts on Thursday, is `complete' (Heshvan and Kislev each
1061have 30 days), and has Passover start on Sunday.")
1062
9c68082d 1063;; The seven leap year types (keviot).
8fc9e5a0 1064(defconst calendar-hebrew-year-Saturday-incomplete-Tuesday
4b112ac4 1065 [nil 52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1066 23 24 25 26 27 nil 28 29 30 31 32 33 34 35 36 37 38 39 40 [41 42]
1067 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1068 "The structure of the parashiot.
1069Hebrew year that starts on Saturday, is `incomplete' (Heshvan and Kislev each
1070have 29 days), and has Passover start on Tuesday.")
1071
8fc9e5a0 1072(defconst calendar-hebrew-year-Saturday-complete-Thursday
4b112ac4 1073 [nil 52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1074 23 24 25 26 27 nil 28 29 30 31 32 33 (nil . 34) (34 . 35) (35 . 36)
1075 (36 . 37) (37 . 38) ([38 39] . 39) 40 [41 42] 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1076 "The structure of the parashiot.
1077Hebrew year that starts on Saturday, is `complete' (Heshvan and Kislev each
1078have 30 days), and has Passover start on Thursday.")
1079
8fc9e5a0 1080(defconst calendar-hebrew-year-Monday-incomplete-Thursday
4b112ac4 1081 [51 52 nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1082 23 24 25 26 27 nil 28 29 30 31 32 33 (nil . 34) (34 . 35) (35 . 36)
1083 (36 . 37) (37 . 38) ([38 39] . 39) 40 [41 42] 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1084 "The structure of the parashiot.
1085Hebrew year that starts on Monday, is `incomplete' (Heshvan and Kislev each
1086have 29 days), and has Passover start on Thursday.")
1087
8fc9e5a0 1088(defconst calendar-hebrew-year-Monday-complete-Saturday
4b112ac4 1089 [51 52 nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1090 23 24 25 26 27 nil (nil . 28) (28 . 29) (29 . 30) (30 . 31) (31 . 32)
1091 (32 . 33) (33 . 34) (34 . 35) (35 . 36) (36 . 37) (37 . 38) (38 . 39)
1092 (39 . 40) (40 . 41) ([41 42] . 42) 43 44 45 46 47 48 49 50]
4b112ac4
ER
1093 "The structure of the parashiot.
1094Hebrew year that starts on Monday, is `complete' (Heshvan and Kislev each have
109530 days), and has Passover start on Saturday.")
1096
8fc9e5a0 1097(defconst calendar-hebrew-year-Tuesday-regular-Saturday
4b112ac4 1098 [51 52 nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1099 23 24 25 26 27 nil (nil . 28) (28 . 29) (29 . 30) (30 . 31) (31 . 32)
1100 (32 . 33) (33 . 34) (34 . 35) (35 . 36) (36 . 37) (37 . 38) (38 . 39)
1101 (39 . 40) (40 . 41) ([41 42] . 42) 43 44 45 46 47 48 49 50]
4b112ac4
ER
1102 "The structure of the parashiot.
1103Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29 days and
1104Kislev has 30 days), and has Passover start on Saturday.")
1105
8fc9e5a0 1106(defconst calendar-hebrew-year-Thursday-incomplete-Sunday
4b112ac4 1107 [52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1108 23 24 25 26 27 28 nil 29 30 31 32 33 34 35 36 37 38 39 40 41 42
1109 43 44 45 46 47 48 49 50]
4b112ac4
ER
1110 "The structure of the parashiot.
1111Hebrew year that starts on Thursday, is `incomplete' (Heshvan and Kislev both
1112have 29 days), and has Passover start on Sunday.")
1113
8fc9e5a0 1114(defconst calendar-hebrew-year-Thursday-complete-Tuesday
4b112ac4 1115 [52 nil nil 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
71ea27ee
GM
1116 23 24 25 26 27 28 nil 29 30 31 32 33 34 35 36 37 38 39 40 41 42
1117 43 44 45 46 47 48 49 [50 51]]
4b112ac4
ER
1118 "The structure of the parashiot.
1119Hebrew year that starts on Thursday, is `complete' (Heshvan and Kislev both
1120have 30 days), and has Passover start on Tuesday.")
1121
711d00e7 1122;;;###diary-autoload
8fc9e5a0 1123(defun diary-hebrew-parasha (&optional mark)
711d00e7
GM
1124 "Parasha diary entry--entry applies if date is a Saturday.
1125An optional parameter MARK specifies a face or single-character string to
1126use when highlighting the day in the calendar."
1127 (let ((d (calendar-absolute-from-gregorian date)))
1128 (if (= (% d 7) 6) ; Saturday
e803eab7 1129 (let* ((h-year (calendar-extract-year
711d00e7
GM
1130 (calendar-hebrew-from-absolute d)))
1131 (rosh-hashanah
8fc9e5a0 1132 (calendar-hebrew-to-absolute (list 7 1 h-year)))
711d00e7 1133 (passover
8fc9e5a0 1134 (calendar-hebrew-to-absolute (list 1 15 h-year)))
711d00e7
GM
1135 (rosh-hashanah-day
1136 (aref calendar-day-name-array (% rosh-hashanah 7)))
1137 (passover-day
1138 (aref calendar-day-name-array (% passover 7)))
8fc9e5a0
GM
1139 (long-h (calendar-hebrew-long-heshvan-p h-year))
1140 (short-k (calendar-hebrew-short-kislev-p h-year))
711d00e7
GM
1141 (type (cond ((and long-h (not short-k)) "complete")
1142 ((and (not long-h) short-k) "incomplete")
1143 (t "regular")))
1144 (year-format
1145 (symbol-value
8fc9e5a0 1146 (intern (format "calendar-hebrew-year-%s-%s-%s" ; keviah
711d00e7
GM
1147 rosh-hashanah-day type passover-day))))
1148 (first-saturday ; of Hebrew year
1149 (calendar-dayname-on-or-before 6 (+ 6 rosh-hashanah)))
1150 (saturday ; which Saturday of the Hebrew year
1151 (/ (- d first-saturday) 7))
1152 (parasha (aref year-format saturday)))
1153 (if parasha
1154 (cons mark
1155 (format
1156 "Parashat %s"
1157 (if (listp parasha) ; Israel differs from diaspora
1158 (if (car parasha)
1159 (format "%s (diaspora), %s (Israel)"
8fc9e5a0 1160 (calendar-hebrew-parasha-name
711d00e7 1161 (car parasha))
8fc9e5a0 1162 (calendar-hebrew-parasha-name
711d00e7
GM
1163 (cdr parasha)))
1164 (format "%s (Israel)"
8fc9e5a0 1165 (calendar-hebrew-parasha-name
711d00e7 1166 (cdr parasha))))
8fc9e5a0
GM
1167 (calendar-hebrew-parasha-name parasha)))))))))
1168
1169(define-obsolete-function-alias 'diary-parasha 'diary-hebrew-parasha "23.1")
711d00e7 1170
87e1e9cd
GM
1171
1172(declare-function solar-setup "solar" ())
1173(declare-function solar-sunrise-sunset "solar" (date))
1174(defvar calendar-latitude)
1175(defvar calendar-longitude)
1176(defvar calendar-time-zone)
1177
1178
9ee4e581 1179;; To be called from diary-list-sexp-entries, where DATE is bound.
87e1e9cd
GM
1180;;;###diary-autoload
1181(defun diary-hebrew-sabbath-candles (&optional mark)
1182 "Local time of candle lighting diary entry--applies if date is a Friday.
1183No diary entry if there is no sunset on that date. Uses
1184`diary-hebrew-sabbath-candles-minutes'.
1185
1186An optional parameter MARK specifies a face or single-character string to
1187use when highlighting the day in the calendar."
1188 (require 'solar)
1189 (or (and calendar-latitude calendar-longitude calendar-time-zone)
1190 (solar-setup))
1191 (if (= (% (calendar-absolute-from-gregorian date) 7) 5) ; Friday
d347df4f 1192 (let ((sunset (cadr (solar-sunrise-sunset date))))
87e1e9cd 1193 (if sunset
d347df4f
GM
1194 (cons mark (format
1195 "%s Sabbath candle lighting"
1196 (apply 'solar-time-string
1197 (cons (- (car sunset)
1198 (/ diary-hebrew-sabbath-candles-minutes
1199 60.0))
1200 (cdr sunset)))))))))
87e1e9cd
GM
1201
1202;;;###diary-autoload
1203(define-obsolete-function-alias 'diary-sabbath-candles
1204 'diary-hebrew-sabbath-candles "23.1")
1205
1206
4b112ac4
ER
1207(provide 'cal-hebrew)
1208
1209;;; cal-hebrew.el ends here