Mercurial > emacs
comparison lisp/calendar/cal-persia.el @ 92820:693124d99e7c
Re-format comments.
(persian-calendar-month-name-array)
(persian-calendar-epoch, calendar-persian-date-string): Doc fixes.
(persian-prompt-for-date): Remove local variable `today'.
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Thu, 13 Mar 2008 03:56:26 +0000 |
parents | f49e5129551f |
children | 2bcff1e54131 |
comparison
equal
deleted
inserted
replaced
92819:8863bb0c2832 | 92820:693124d99e7c |
---|---|
34 | 34 |
35 (require 'cal-julian) | 35 (require 'cal-julian) |
36 | 36 |
37 (defconst persian-calendar-month-name-array | 37 (defconst persian-calendar-month-name-array |
38 ["Farvardin" "Ordibehest" "Xordad" "Tir" "Mordad" "Sahrivar" "Mehr" "Aban" | 38 ["Farvardin" "Ordibehest" "Xordad" "Tir" "Mordad" "Sahrivar" "Mehr" "Aban" |
39 "Azar" "Dey" "Bahman" "Esfand"]) | 39 "Azar" "Dey" "Bahman" "Esfand"] |
40 "Names of the months in the Persian calendar.") | |
40 | 41 |
41 (defconst persian-calendar-epoch (calendar-absolute-from-julian '(3 19 622)) | 42 (defconst persian-calendar-epoch (calendar-absolute-from-julian '(3 19 622)) |
42 "Absolute date of start of Persian calendar = March 19, 622 A.D. (Julian).") | 43 "Absolute date of start of Persian calendar = March 19, 622 AD (Julian).") |
43 | 44 |
44 (defun persian-calendar-leap-year-p (year) | 45 (defun persian-calendar-leap-year-p (year) |
45 "True if YEAR is a leap year on the Persian calendar." | 46 "True if YEAR is a leap year on the Persian calendar." |
46 (< (mod (* (mod (mod (if (<= 0 year) | 47 (< (mod (* (mod (mod (if (<= 0 year) |
47 (+ year 2346) ; no year zero | 48 (+ year 2346) ; no year zero |
68 (year (extract-calendar-year date))) | 69 (year (extract-calendar-year date))) |
69 (if (< year 0) | 70 (if (< year 0) |
70 (+ (calendar-absolute-from-persian | 71 (+ (calendar-absolute-from-persian |
71 (list month day (1+ (mod year 2820)))) | 72 (list month day (1+ (mod year 2820)))) |
72 (* 1029983 (floor year 2820))) | 73 (* 1029983 (floor year 2820))) |
73 (+ (1- persian-calendar-epoch); Days before epoch | 74 (+ (1- persian-calendar-epoch) ; days before epoch |
74 (* 365 (1- year)) ; Days in prior years. | 75 (* 365 (1- year)) ; days in prior years |
75 (* 683 ; Leap days in prior 2820-year cycles | 76 (* 683 ; leap days in prior 2820-year cycles |
76 (floor (+ year 2345) 2820)) | 77 (floor (+ year 2345) 2820)) |
77 (* 186 ; Leap days in prior 768 year cycles | 78 (* 186 ; leap days in prior 768 year cycles |
78 (floor (mod (+ year 2345) 2820) 768)) | 79 (floor (mod (+ year 2345) 2820) 768)) |
79 (floor; Leap years in current 768 or 516 year cycle | 80 (floor ; leap years in current 768 or 516 year cycle |
80 (* 683 (mod (mod (+ year 2345) 2820) 768)) | 81 (* 683 (mod (mod (+ year 2345) 2820) 768)) |
81 2820) | 82 2820) |
82 -568 ; Leap years in Persian years -2345...-1 | 83 -568 ; leap years in Persian years -2345...-1 |
83 (calendar-sum ; Days in prior months this year. | 84 (calendar-sum ; days in prior months this year |
84 m 1 (< m month) | 85 m 1 (< m month) |
85 (persian-calendar-last-day-of-month m year)) | 86 (persian-calendar-last-day-of-month m year)) |
86 day)))) ; Days so far this month. | 87 day)))) ; days so far this month |
87 | 88 |
88 (defun calendar-persian-year-from-absolute (date) | 89 (defun calendar-persian-year-from-absolute (date) |
89 "Persian year corresponding to the absolute DATE." | 90 "Persian year corresponding to the absolute DATE." |
90 (let* ((d0 ; Prior days since start of 2820 cycles | 91 (let* ((d0 ; prior days since start of 2820 cycles |
91 (- date (calendar-absolute-from-persian (list 1 1 -2345)))) | 92 (- date (calendar-absolute-from-persian (list 1 1 -2345)))) |
92 (n2820 ; Completed 2820-year cycles | 93 (n2820 ; completed 2820-year cycles |
93 (floor d0 1029983)) | 94 (floor d0 1029983)) |
94 (d1 ; Prior days not in n2820 | 95 (d1 ; prior days not in n2820 |
95 (mod d0 1029983)) | 96 (mod d0 1029983)) |
96 (n768 ; 768-year cycles not in n2820 | 97 (n768 ; 768-year cycles not in n2820 |
97 (floor d1 280506)) | 98 (floor d1 280506)) |
98 (d2 ; Prior days not in n2820 or n768 | 99 (d2 ; prior days not in n2820 or n768 |
99 (mod d1 280506)) | 100 (mod d1 280506)) |
100 (n1 ; Years not in n2820 or n768 | 101 (n1 ; years not in n2820 or n768 |
101 ; we want is | 102 ;; Want: |
102 ; (floor (+ (* 2820 d2) (* 2820 366)) 1029983)) | 103 ;; (floor (+ (* 2820 d2) (* 2820 366)) 1029983)) |
103 ; but that causes overflow, so we use | 104 ;; but that causes overflow, so use the following. |
104 (let ((a (floor d2 366)); we use 366 as the divisor because | 105 ;; Use 366 as the divisor because (2820*366 mod 1029983) is small. |
105 ; (2820*366 mod 1029983) is small | 106 (let ((a (floor d2 366)) |
106 (b (mod d2 366))) | 107 (b (mod d2 366))) |
107 (+ 1 a (floor (+ (* 2137 a) (* 2820 b) 2137) 1029983)))) | 108 (+ 1 a (floor (+ (* 2137 a) (* 2820 b) 2137) 1029983)))) |
108 (year (+ (* 2820 n2820); Complete 2820 year cycles | 109 (year (+ (* 2820 n2820) ; complete 2820 year cycles |
109 (* 768 n768) ; Complete 768 year cycles | 110 (* 768 n768) ; complete 768 year cycles |
110 (if ; Remaining years | 111 ;; Remaining years. |
111 ; Last day of 2820 year cycle | 112 (if (= d1 1029617) ; last day of 2820 year cycle |
112 (= d1 1029617) | |
113 (1- n1) | 113 (1- n1) |
114 n1) | 114 n1) |
115 -2345))) ; Years before year 1 | 115 -2345))) ; years before year 1 |
116 (if (< year 1) | 116 (if (< year 1) |
117 (1- year); No year zero | 117 (1- year) ; no year zero |
118 year))) | 118 year))) |
119 | 119 |
120 (defun calendar-persian-from-absolute (date) | 120 (defun calendar-persian-from-absolute (date) |
121 "Compute the Persian equivalent for absolute date DATE. | 121 "Compute the Persian equivalent for absolute date DATE. |
122 The result is a list of the form (MONTH DAY YEAR). | 122 The result is a list of the form (MONTH DAY YEAR). |
123 The absolute date is the number of days elapsed since the imaginary | 123 The absolute date is the number of days elapsed since the imaginary |
124 Gregorian date Sunday, December 31, 1 BC." | 124 Gregorian date Sunday, December 31, 1 BC." |
125 (let* ((year (calendar-persian-year-from-absolute date)) | 125 (let* ((year (calendar-persian-year-from-absolute date)) |
126 (month ; Search forward from Farvardin | 126 (month ; search forward from Farvardin |
127 (1+ (calendar-sum m 1 | 127 (1+ (calendar-sum m 1 |
128 (> date | 128 (> date |
129 (calendar-absolute-from-persian | 129 (calendar-absolute-from-persian |
130 (list | 130 (list |
131 m | 131 m |
132 (persian-calendar-last-day-of-month m year) | 132 (persian-calendar-last-day-of-month m year) |
133 year))) | 133 year))) |
134 1))) | 134 1))) |
135 (day ; Calculate the day by subtraction | 135 (day ; calculate the day by subtraction |
136 (- date (1- (calendar-absolute-from-persian | 136 (- date (1- (calendar-absolute-from-persian |
137 (list month 1 year)))))) | 137 (list month 1 year)))))) |
138 (list month day year))) | 138 (list month day year))) |
139 | 139 |
140 ;;;###autoload | 140 ;;;###autoload |
141 (defun calendar-persian-date-string (&optional date) | 141 (defun calendar-persian-date-string (&optional date) |
142 "String of Persian date of Gregorian DATE. | 142 "String of Persian date of Gregorian DATE, default today." |
143 Defaults to today's date if DATE is not given." | |
144 (let* ((persian-date (calendar-persian-from-absolute | 143 (let* ((persian-date (calendar-persian-from-absolute |
145 (calendar-absolute-from-gregorian | 144 (calendar-absolute-from-gregorian |
146 (or date (calendar-current-date))))) | 145 (or date (calendar-current-date))))) |
147 (y (extract-calendar-year persian-date)) | 146 (y (extract-calendar-year persian-date)) |
148 (m (extract-calendar-month persian-date))) | 147 (m (extract-calendar-month persian-date))) |
169 (calendar-absolute-from-persian date))) | 168 (calendar-absolute-from-persian date))) |
170 (or noecho (calendar-print-persian-date))) | 169 (or noecho (calendar-print-persian-date))) |
171 | 170 |
172 (defun persian-prompt-for-date () | 171 (defun persian-prompt-for-date () |
173 "Ask for a Persian date." | 172 "Ask for a Persian date." |
174 (let* ((today (calendar-current-date)) | 173 (let* ((year (calendar-read |
175 (year (calendar-read | |
176 "Persian calendar year (not 0): " | 174 "Persian calendar year (not 0): " |
177 (lambda (x) (not (zerop x))) | 175 (lambda (x) (not (zerop x))) |
178 (int-to-string | 176 (int-to-string |
179 (extract-calendar-year | 177 (extract-calendar-year |
180 (calendar-persian-from-absolute | 178 (calendar-persian-from-absolute |
181 (calendar-absolute-from-gregorian today)))))) | 179 (calendar-absolute-from-gregorian |
180 (calendar-current-date))))))) | |
182 (completion-ignore-case t) | 181 (completion-ignore-case t) |
183 (month (cdr (assoc | 182 (month (cdr (assoc |
184 (completing-read | 183 (completing-read |
185 "Persian calendar month name: " | 184 "Persian calendar month name: " |
186 (mapcar 'list | 185 (mapcar 'list |