cal-coptic.el 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. ;;; cal-coptic.el --- calendar functions for the Coptic/Ethiopic calendars
  2. ;; Copyright (C) 1995, 1997, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
  4. ;; Maintainer: Glenn Morris <rgm@gnu.org>
  5. ;; Keywords: calendar
  6. ;; Human-Keywords: Coptic calendar, Ethiopic calendar, calendar, diary
  7. ;; Package: calendar
  8. ;; This file is part of GNU Emacs.
  9. ;; GNU Emacs is free software: you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; GNU Emacs is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Commentary:
  20. ;; See calendar.el.
  21. ;;; Code:
  22. (require 'calendar)
  23. ;; Not constants because they get let-bound.
  24. (defvar calendar-coptic-month-name-array
  25. ["Tut" "Babah" "Hatur" "Kiyahk" "Tubah" "Amshir" "Baramhat" "Barmundah"
  26. "Bashans" "Baunah" "Abib" "Misra" "al-Nasi"]
  27. "Array of the month names in the Coptic calendar.")
  28. (eval-and-compile
  29. (autoload 'calendar-julian-to-absolute "cal-julian"))
  30. (defvar calendar-coptic-epoch
  31. (eval-when-compile (calendar-julian-to-absolute '(8 29 284)))
  32. "Absolute date of start of Coptic calendar = August 29, 284 AD (Julian).")
  33. (defvar calendar-coptic-name "Coptic"
  34. "Used in some message strings.")
  35. (defun calendar-coptic-leap-year-p (year)
  36. "True if YEAR is a leap year on the Coptic calendar."
  37. (zerop (mod (1+ year) 4)))
  38. (defun calendar-coptic-last-day-of-month (month year)
  39. "Return last day of MONTH, YEAR on the Coptic calendar.
  40. The 13th month is not really a month, but the 5 (6 in leap years) day period of
  41. Nisi (Kebus) at the end of the year."
  42. (if (< month 13)
  43. 30
  44. (if (calendar-coptic-leap-year-p year)
  45. 6
  46. 5)))
  47. (defun calendar-coptic-to-absolute (date)
  48. "Compute absolute date from Coptic date DATE.
  49. The absolute date is the number of days elapsed since the (imaginary)
  50. Gregorian date Sunday, December 31, 1 BC."
  51. (let ((month (calendar-extract-month date))
  52. (day (calendar-extract-day date))
  53. (year (calendar-extract-year date)))
  54. (+ (1- calendar-coptic-epoch) ; days before start of calendar
  55. (* 365 (1- year)) ; days in prior years
  56. (/ year 4) ; leap days in prior years
  57. (* 30 (1- month)) ; days in prior months this year
  58. day))) ; days so far this month
  59. (define-obsolete-function-alias 'calendar-absolute-from-coptic
  60. 'calendar-coptic-to-absolute "23.1")
  61. (defun calendar-coptic-from-absolute (date)
  62. "Compute the Coptic equivalent for absolute date DATE.
  63. The result is a list of the form (MONTH DAY YEAR).
  64. The absolute date is the number of days elapsed since the imaginary
  65. Gregorian date Sunday, December 31, 1 BC."
  66. (if (< date calendar-coptic-epoch)
  67. (list 0 0 0) ; pre-Coptic date
  68. (let* ((approx (/ (- date calendar-coptic-epoch)
  69. 366)) ; approximation from below
  70. (year ; search forward from the approximation
  71. (+ approx
  72. (calendar-sum y approx
  73. (>= date (calendar-coptic-to-absolute
  74. (list 1 1 (1+ y))))
  75. 1)))
  76. (month ; search forward from Tot
  77. (1+ (calendar-sum m 1
  78. (> date
  79. (calendar-coptic-to-absolute
  80. (list m
  81. (calendar-coptic-last-day-of-month m
  82. year)
  83. year)))
  84. 1)))
  85. (day ; calculate the day by subtraction
  86. (- date
  87. (1- (calendar-coptic-to-absolute (list month 1 year))))))
  88. (list month day year))))
  89. ;;;###cal-autoload
  90. (defun calendar-coptic-date-string (&optional date)
  91. "String of Coptic date of Gregorian DATE.
  92. Returns the empty string if DATE is pre-Coptic calendar.
  93. Defaults to today's date if DATE is not given."
  94. (let* ((coptic-date (calendar-coptic-from-absolute
  95. (calendar-absolute-from-gregorian
  96. (or date (calendar-current-date)))))
  97. (y (calendar-extract-year coptic-date))
  98. (m (calendar-extract-month coptic-date)))
  99. (if (< y 1)
  100. ""
  101. (let ((monthname (aref calendar-coptic-month-name-array (1- m)))
  102. (day (number-to-string (calendar-extract-day coptic-date)))
  103. (dayname nil)
  104. (month (number-to-string m))
  105. (year (number-to-string y)))
  106. (mapconcat 'eval calendar-date-display-form "")))))
  107. ;;;###cal-autoload
  108. (defun calendar-coptic-print-date ()
  109. "Show the Coptic calendar equivalent of the selected date."
  110. (interactive)
  111. (let ((f (calendar-coptic-date-string (calendar-cursor-to-date t))))
  112. (if (string-equal f "")
  113. (message "Date is pre-%s calendar" calendar-coptic-name)
  114. (message "%s date: %s" calendar-coptic-name f))))
  115. (define-obsolete-function-alias 'calendar-print-coptic-date
  116. 'calendar-coptic-print-date "23.1")
  117. (defun calendar-coptic-read-date ()
  118. "Interactively read the arguments for a Coptic date command.
  119. Reads a year, month, and day."
  120. (let* ((today (calendar-current-date))
  121. (year (calendar-read
  122. (format "%s calendar year (>0): " calendar-coptic-name)
  123. (lambda (x) (> x 0))
  124. (number-to-string
  125. (calendar-extract-year
  126. (calendar-coptic-from-absolute
  127. (calendar-absolute-from-gregorian today))))))
  128. (completion-ignore-case t)
  129. (month (cdr (assoc-string
  130. (completing-read
  131. (format "%s calendar month name: " calendar-coptic-name)
  132. (mapcar 'list
  133. (append calendar-coptic-month-name-array nil))
  134. nil t)
  135. (calendar-make-alist calendar-coptic-month-name-array
  136. 1) t)))
  137. (last (calendar-coptic-last-day-of-month month year))
  138. (day (calendar-read
  139. (format "%s calendar day (1-%d): " calendar-coptic-name last)
  140. (lambda (x) (and (< 0 x) (<= x last))))))
  141. (list (list month day year))))
  142. (define-obsolete-function-alias 'coptic-prompt-for-date
  143. 'calendar-coptic-read-date "23.1")
  144. ;;;###cal-autoload
  145. (defun calendar-coptic-goto-date (date &optional noecho)
  146. "Move cursor to Coptic date DATE.
  147. Echo Coptic date unless NOECHO is t."
  148. (interactive (calendar-coptic-read-date))
  149. (calendar-goto-date (calendar-gregorian-from-absolute
  150. (calendar-coptic-to-absolute date)))
  151. (or noecho (calendar-coptic-print-date)))
  152. (define-obsolete-function-alias 'calendar-goto-coptic-date
  153. 'calendar-coptic-goto-date "23.1")
  154. (defvar date)
  155. ;; To be called from diary-list-sexp-entries, where DATE is bound.
  156. ;;;###diary-autoload
  157. (defun diary-coptic-date ()
  158. "Coptic calendar equivalent of date diary entry."
  159. (let ((f (calendar-coptic-date-string date)))
  160. (if (string-equal f "")
  161. (format "Date is pre-%s calendar" calendar-coptic-name)
  162. (format "%s date: %s" calendar-coptic-name f))))
  163. (defconst calendar-ethiopic-month-name-array
  164. ["Maskaram" "Teqemt" "Khedar" "Takhsas" "Ter" "Yakatit" "Magabit" "Miyazya"
  165. "Genbot" "Sane" "Hamle" "Nahas" "Paguem"]
  166. "Array of the month names in the Ethiopic calendar.")
  167. (defconst calendar-ethiopic-epoch 2796
  168. "Absolute date of start of Ethiopic calendar = August 29, 8 C.E. (Julian).")
  169. (defconst calendar-ethiopic-name "Ethiopic"
  170. "Used in some message strings.")
  171. (defun calendar-ethiopic-to-absolute (date)
  172. "Compute absolute date from Ethiopic date DATE.
  173. The absolute date is the number of days elapsed since the (imaginary)
  174. Gregorian date Sunday, December 31, 1 BC."
  175. (let ((calendar-coptic-epoch calendar-ethiopic-epoch))
  176. (calendar-coptic-to-absolute date)))
  177. (define-obsolete-function-alias 'calendar-absolute-from-ethiopic
  178. 'calendar-ethiopic-to-absolute "23.1")
  179. (defun calendar-ethiopic-from-absolute (date)
  180. "Compute the Ethiopic equivalent for absolute date DATE.
  181. The result is a list of the form (MONTH DAY YEAR).
  182. The absolute date is the number of days elapsed since the imaginary
  183. Gregorian date Sunday, December 31, 1 BC."
  184. (let ((calendar-coptic-epoch calendar-ethiopic-epoch))
  185. (calendar-coptic-from-absolute date)))
  186. ;;;###cal-autoload
  187. (defun calendar-ethiopic-date-string (&optional date)
  188. "String of Ethiopic date of Gregorian DATE.
  189. Returns the empty string if DATE is pre-Ethiopic calendar.
  190. Defaults to today's date if DATE is not given."
  191. (let ((calendar-coptic-epoch calendar-ethiopic-epoch)
  192. (calendar-coptic-name calendar-ethiopic-name)
  193. (calendar-coptic-month-name-array calendar-ethiopic-month-name-array))
  194. (calendar-coptic-date-string date)))
  195. ;;;###cal-autoload
  196. (defun calendar-ethiopic-print-date ()
  197. "Show the Ethiopic calendar equivalent of the selected date."
  198. (interactive)
  199. (let ((calendar-coptic-epoch calendar-ethiopic-epoch)
  200. (calendar-coptic-name calendar-ethiopic-name)
  201. (calendar-coptic-month-name-array calendar-ethiopic-month-name-array))
  202. (call-interactively 'calendar-coptic-print-date)))
  203. (define-obsolete-function-alias 'calendar-print-ethiopic-date
  204. 'calendar-ethiopic-print-date "23.1")
  205. ;;;###cal-autoload
  206. (defun calendar-ethiopic-goto-date (date &optional noecho)
  207. "Move cursor to Ethiopic date DATE.
  208. Echo Ethiopic date unless NOECHO is t."
  209. (interactive
  210. (let ((calendar-coptic-epoch calendar-ethiopic-epoch)
  211. (calendar-coptic-name calendar-ethiopic-name)
  212. (calendar-coptic-month-name-array calendar-ethiopic-month-name-array))
  213. (calendar-coptic-read-date)))
  214. (calendar-goto-date (calendar-gregorian-from-absolute
  215. (calendar-ethiopic-to-absolute date)))
  216. (or noecho (calendar-ethiopic-print-date)))
  217. (define-obsolete-function-alias 'calendar-goto-ethiopic-date
  218. 'calendar-ethiopic-goto-date "23.1")
  219. ;; To be called from diary-list-sexp-entries, where DATE is bound.
  220. ;;;###diary-autoload
  221. (defun diary-ethiopic-date ()
  222. "Ethiopic calendar equivalent of date diary entry."
  223. (let ((calendar-coptic-epoch calendar-ethiopic-epoch)
  224. (calendar-coptic-name calendar-ethiopic-name)
  225. (calendar-coptic-month-name-array calendar-ethiopic-month-name-array))
  226. (diary-coptic-date)))
  227. (provide 'cal-coptic)
  228. ;;; cal-coptic.el ends here