diff options
| author | Edward M. Reingold | 1995-10-23 22:19:07 +0000 |
|---|---|---|
| committer | Edward M. Reingold | 1995-10-23 22:19:07 +0000 |
| commit | 0031509cd8dab1f17b465bcda61bc29329c877e7 (patch) | |
| tree | f5e913636a9298936efe71843288103a337a0a14 | |
| parent | a5038ae59521c7572095584a8972bd45a79e631b (diff) | |
| download | emacs-0031509cd8dab1f17b465bcda61bc29329c877e7.tar.gz emacs-0031509cd8dab1f17b465bcda61bc29329c877e7.zip | |
Completely rewritten!
| -rw-r--r-- | lisp/calendar/cal-china.el | 331 |
1 files changed, 243 insertions, 88 deletions
diff --git a/lisp/calendar/cal-china.el b/lisp/calendar/cal-china.el index 1f4c4027f93..59c6d061a18 100644 --- a/lisp/calendar/cal-china.el +++ b/lisp/calendar/cal-china.el | |||
| @@ -25,9 +25,18 @@ | |||
| 25 | ;;; Commentary: | 25 | ;;; Commentary: |
| 26 | 26 | ||
| 27 | ;; This collection of functions implements the features of calendar.el, | 27 | ;; This collection of functions implements the features of calendar.el, |
| 28 | ;; diary.el, and holidays.el that deal with the Chinese calendar. It was | 28 | ;; diary.el, and holidays.el that deal with the Chinese calendar. The rules |
| 29 | ;; written by | 29 | ;; used for the Chinese calendar are those of Baolin Liu (see L. E. Doggett's |
| 30 | 30 | ;; article "Calendars" in the Explanatory Supplement to the Astronomical | |
| 31 | ;; Almanac, second edition, 1992) for the calendar as revised at the beginning | ||
| 32 | ;; of the Qing dynasty in 1644. Liu's rules produce a calendar for 2033 which | ||
| 33 | ;; is not accepted by all authorities. Furthermore, the nature of the | ||
| 34 | ;; astronomical calculations is such that precise calculations cannot be made | ||
| 35 | ;; without great expense in time, so that the calendars produced may not agree | ||
| 36 | ;; perfectly with published tables--but no two pairs of published tables agree | ||
| 37 | ;; perfectly either! | ||
| 38 | |||
| 39 | ;; Comments, corrections, and improvements should be sent to | ||
| 31 | ;; Edward M. Reingold Department of Computer Science | 40 | ;; Edward M. Reingold Department of Computer Science |
| 32 | ;; (217) 333-6733 University of Illinois at Urbana-Champaign | 41 | ;; (217) 333-6733 University of Illinois at Urbana-Champaign |
| 33 | ;; reingold@cs.uiuc.edu 1304 West Springfield Avenue | 42 | ;; reingold@cs.uiuc.edu 1304 West Springfield Avenue |
| @@ -101,8 +110,7 @@ Chinese calendar. Default is for no daylight savings time.") | |||
| 101 | "Absolute date of first new Zodiac sign on or after absolute date d. | 110 | "Absolute date of first new Zodiac sign on or after absolute date d. |
| 102 | The Zodiac signs begin when the sun's longitude is a multiple of 30 degrees." | 111 | The Zodiac signs begin when the sun's longitude is a multiple of 30 degrees." |
| 103 | (let* ((year (extract-calendar-year | 112 | (let* ((year (extract-calendar-year |
| 104 | (calendar-gregorian-from-absolute | 113 | (calendar-gregorian-from-absolute d))) |
| 105 | (floor (calendar-absolute-from-astro d))))) | ||
| 106 | (calendar-time-zone (eval chinese-calendar-time-zone)) | 114 | (calendar-time-zone (eval chinese-calendar-time-zone)) |
| 107 | (calendar-daylight-time-offset | 115 | (calendar-daylight-time-offset |
| 108 | chinese-calendar-daylight-time-offset) | 116 | chinese-calendar-daylight-time-offset) |
| @@ -148,6 +156,159 @@ The Zodiac signs begin when the sun's longitude is a multiple of 30 degrees." | |||
| 148 | (lunar-new-moon-on-or-after | 156 | (lunar-new-moon-on-or-after |
| 149 | (calendar-astro-from-absolute d)))))) | 157 | (calendar-astro-from-absolute d)))))) |
| 150 | 158 | ||
| 159 | (defvar chinese-year-cache | ||
| 160 | '((1989 (12 . 726110) (1 . 726139) (2 . 726169) (3 . 726198) (4 . 726227) | ||
| 161 | (5 . 726257) (6 . 726286) (7 . 726316) (8 . 726345) (9 . 726375) | ||
| 162 | (10 . 726404) (11 . 726434)) | ||
| 163 | (1990 (12 . 726464) (1 . 726494) (2 . 726523) (3 . 726553) (4 . 726582) | ||
| 164 | (5 . 726611) (5.5 . 726641) (6 . 726670) (7 . 726699) (8 . 726729) | ||
| 165 | (9 . 726758) (10 . 726788) (11 . 726818)) | ||
| 166 | (1991 (12 . 726848) (1 . 726878) (2 . 726907) (3 . 726937) (4 . 726966) | ||
| 167 | (5 . 726995) (6 . 727025) (7 . 727054) (8 . 727083) (9 . 727113) | ||
| 168 | (10 . 727142) (11 . 727172)) | ||
| 169 | (1992 (12 . 727202) (1 . 727232) (2 . 727261) (3 . 727291) (4 . 727321) | ||
| 170 | (5 . 727350) (6 . 727379) (7 . 727409) (8 . 727438) (9 . 727467) | ||
| 171 | (10 . 727497) (11 . 727526)) | ||
| 172 | (1993 (12 . 727556) (1 . 727586) (2 . 727615) (3 . 727645) (3.5 . 727675) | ||
| 173 | (4 . 727704) (5 . 727734) (6 . 727763) (7 . 727793) (8 . 727822) | ||
| 174 | (9 . 727851) (10 . 727881) (11 . 727910)) | ||
| 175 | (1994 (12 . 727940) (1 . 727969) (2 . 727999) (3 . 728029) (4 . 728059) | ||
| 176 | (5 . 728088) (6 . 728118) (7 . 728147) (8 . 728177) (9 . 728206) | ||
| 177 | (10 . 728235) (11 . 728265)) | ||
| 178 | (1995 (12 . 728294) (1 . 728324) (2 . 728353) (3 . 728383) (4 . 728413) | ||
| 179 | (5 . 728442) (6 . 728472) (7 . 728501) (8 . 728531) (8.5 . 728561) | ||
| 180 | (9 . 728590) (10 . 728619) (11 . 728649)) | ||
| 181 | (1996 (12 . 728678) (1 . 728708) (2 . 728737) (3 . 728767) (4 . 728796) | ||
| 182 | (5 . 728826) (6 . 728856) (7 . 728885) (8 . 728915) (9 . 728944) | ||
| 183 | (10 . 728974) (11 . 729004)) | ||
| 184 | (1997 (12 . 729033) (1 . 729062) (2 . 729092) (3 . 729121) (4 . 729151) | ||
| 185 | (5 . 729180) (6 . 729210) (7 . 729239) (8 . 729269) (9 . 729299) | ||
| 186 | (10 . 729328) (11 . 729358)) | ||
| 187 | (1998 (12 . 729388) (1 . 729417) (2 . 729447) (3 . 729476) (4 . 729505) | ||
| 188 | (5 . 729535) (5.5 . 729564) (6 . 729593) (7 . 729623) (8 . 729653) | ||
| 189 | (9 . 729682) (10 . 729712) (11 . 729742)) | ||
| 190 | (1999 (12 . 729771) (1 . 729801) (2 . 729831) (3 . 729860) (4 . 729889) | ||
| 191 | (5 . 729919) (6 . 729948) (7 . 729977) (8 . 730007) (9 . 730036) | ||
| 192 | (10 . 730066) (11 . 730096)) | ||
| 193 | (2000 (12 . 730126) (1 . 730155) (2 . 730185) (3 . 730215) (4 . 730244) | ||
| 194 | (5 . 730273) (6 . 730303) (7 . 730332) (8 . 730361) (9 . 730391) | ||
| 195 | (10 . 730420) (11 . 730450))) | ||
| 196 | "An assoc list of Chinese year structures as determined by `chinese-year'. | ||
| 197 | |||
| 198 | Values are computed as needed, but to save time, the initial value consists | ||
| 199 | of the precomputed years 1989-2000. The code works just as well with this | ||
| 200 | set to nil initially (which is how the value for 1989-2000 was computed).") | ||
| 201 | |||
| 202 | (defun chinese-year (y) | ||
| 203 | "The structure of the Chinese year for Gregorian year Y. | ||
| 204 | The result is a list of pairs (i . d), where month i begins on absolute date d, | ||
| 205 | of the Chinese months from the Chinese month following the solstice in | ||
| 206 | Gregorian year Y-1 to the Chinese month of the solstice of Gregorian year Y. | ||
| 207 | |||
| 208 | The list is cached for further use." | ||
| 209 | (let ((list (cdr (assoc y chinese-year-cache)))) | ||
| 210 | (if (not list) | ||
| 211 | (progn | ||
| 212 | (setq list (compute-chinese-year y)) | ||
| 213 | (setq chinese-year-cache | ||
| 214 | (append chinese-year-cache (list (cons y list)))))) | ||
| 215 | list)) | ||
| 216 | |||
| 217 | (defun number-chinese-months (list start &optional no-leap-months) | ||
| 218 | "Assign month numbers to the lunar months in LIST, starting with START. | ||
| 219 | |||
| 220 | If optional parameter NO-LEAP-MONTHS is true, just number the months | ||
| 221 | sequentially, ignoring the usual leap month rule. | ||
| 222 | |||
| 223 | First month of list will never be a leap month, nor will the last. | ||
| 224 | |||
| 225 | Numbers are assigned sequentially mod 12 (but using 12 instead of 0)." | ||
| 226 | (if list | ||
| 227 | (if no-leap-months | ||
| 228 | (cons (cons (calendar-mod start 12) (car list)) | ||
| 229 | (number-chinese-months (cdr list) (1+ start) t)) | ||
| 230 | (cons | ||
| 231 | ;; first month | ||
| 232 | (cons (calendar-mod start 12) (car list)) | ||
| 233 | ;; remaining months | ||
| 234 | (if (and (cdr (cdr list));; at least two more months... | ||
| 235 | ;; ... and next one is a leap month | ||
| 236 | (<= (car (cdr (cdr list))) | ||
| 237 | (chinese-zodiac-sign-on-or-after (car (cdr list))))) | ||
| 238 | (cons (cons (+ (calendar-mod start 12) 0.5) (car (cdr list))) | ||
| 239 | (number-chinese-months (cdr (cdr list)) (1+ start) t)) | ||
| 240 | ;; Otherwise, just number the months | ||
| 241 | (number-chinese-months (cdr list) (1+ start))))))) | ||
| 242 | |||
| 243 | (defun chinese-month-list (start end) | ||
| 244 | "List of starting dates of Chinese months from START to END." | ||
| 245 | (if (<= start end) | ||
| 246 | (let ((new-moon (chinese-new-moon-on-or-after start))) | ||
| 247 | (if (<= new-moon end) | ||
| 248 | (append (list new-moon) | ||
| 249 | (chinese-month-list (1+ new-moon) end)))))) | ||
| 250 | |||
| 251 | (defun chinese-leap-months (list low high) | ||
| 252 | "Return list of leap months in LIST with indices in range LOW to HIGH. | ||
| 253 | |||
| 254 | A leap month has a non-integer index." | ||
| 255 | (if list | ||
| 256 | (let ((index (car (car list)))) | ||
| 257 | (if (and (/= index (floor index)) | ||
| 258 | (<= low index) | ||
| 259 | (<= index high)) | ||
| 260 | (cons index (chinese-leap-months (cdr list) low high)) | ||
| 261 | (chinese-leap-months (cdr list) low high))))) | ||
| 262 | |||
| 263 | (defun compute-chinese-year (y) | ||
| 264 | "Compute the structure of the Chinese year for Gregorian year Y. | ||
| 265 | The result is a list of pairs (i . d), where month i begins on absolute date d, | ||
| 266 | of the Chinese months from the Chinese month following the solstice in | ||
| 267 | Gregorian year Y-1 to the Chinese month of the solstice of Gregorian year Y." | ||
| 268 | (let* ((next-solstice (chinese-zodiac-sign-on-or-after | ||
| 269 | (calendar-absolute-from-gregorian | ||
| 270 | (list 12 15 y)))) | ||
| 271 | (list (chinese-month-list (1+ (chinese-zodiac-sign-on-or-after | ||
| 272 | (calendar-absolute-from-gregorian | ||
| 273 | (list 12 15 (1- y))))) | ||
| 274 | next-solstice))) | ||
| 275 | (if (= (length list) 12) | ||
| 276 | ;; No room for a leap month, just number them 12, 1, 2, ..., 11 | ||
| 277 | (number-chinese-months list 0 t) | ||
| 278 | (let* ((had-leap-month (chinese-leap-months (chinese-year (1- y)) 1 10)) | ||
| 279 | (numbered-list) | ||
| 280 | (next-sign;; On or after first month on list | ||
| 281 | (chinese-zodiac-sign-on-or-after (car list)))) | ||
| 282 | ;; Now we can assign numbers to the list for y | ||
| 283 | ;; The first month or two are special | ||
| 284 | (if (and (<= (car list) next-sign) (< next-sign (car (cdr list)))) | ||
| 285 | (progn;; First month on list is not a leap month | ||
| 286 | (setq numbered-list (list (cons 12 (car list)))) | ||
| 287 | (setq list (cdr list)) | ||
| 288 | (setq next-sign (chinese-zodiac-sign-on-or-after (car list)))) | ||
| 289 | ;; First month on list might be a leap month... | ||
| 290 | (if (not had-leap-month);; ... it is a leap month | ||
| 291 | (progn;; First month on list is a leap month, so second is not | ||
| 292 | (setq numbered-list (list (cons 11.5 (car list)) | ||
| 293 | (cons 12 (car (cdr list))))) | ||
| 294 | (setq list (cdr (cdr list))) | ||
| 295 | (setq had-leap-month t)))) | ||
| 296 | (if (and (>= next-sign (car (cdr list))) | ||
| 297 | (not had-leap-month)) | ||
| 298 | (progn;; Second month on list is a leap month | ||
| 299 | (setq numbered-list | ||
| 300 | (append numbered-list (list (cons 12.5 (car list))))) | ||
| 301 | (setq list (cdr list)))) | ||
| 302 | ;; At this point we have a list of new moons for months 1 to 11 for y. | ||
| 303 | ;; We need to see which are leap months. | ||
| 304 | (if (= (length list) 11) | ||
| 305 | ;; There can be no leap months, just number them 1..11 | ||
| 306 | (append numbered-list (number-chinese-months list 1 t)) | ||
| 307 | ;; There is a leap month, but it can't be the first one because that | ||
| 308 | ;; would be 12.5 which we already considered. It also can't be the | ||
| 309 | ;; last one because that has the solstice in it. | ||
| 310 | (append numbered-list (number-chinese-months list 1))))))) | ||
| 311 | |||
| 151 | (defun calendar-absolute-from-chinese (date) | 312 | (defun calendar-absolute-from-chinese (date) |
| 152 | "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. | 313 | "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. |
| 153 | The Gregorian date Sunday, December 31, 1 BC is imaginary." | 314 | The Gregorian date Sunday, December 31, 1 BC is imaginary." |
| @@ -156,85 +317,32 @@ The Gregorian date Sunday, December 31, 1 BC is imaginary." | |||
| 156 | (month (car (cdr (cdr date)))) | 317 | (month (car (cdr (cdr date)))) |
| 157 | (day (car (cdr (cdr (cdr date))))) | 318 | (day (car (cdr (cdr (cdr date))))) |
| 158 | (g-year (+ (* (1- cycle) 60);; years in prior cycles | 319 | (g-year (+ (* (1- cycle) 60);; years in prior cycles |
| 159 | (1- year);; prior years this cycle | 320 | (1- year) ;; prior years this cycle |
| 160 | -2636));; years before absolute date 0 | 321 | -2636))) ;; years before absolute date 0 |
| 161 | (new-year (chinese-new-year g-year)) | 322 | (+ (1- day);; prior days this month |
| 162 | (current-month new-year) | 323 | (cdr ;; absolute date of start of this month |
| 163 | (current-month-number 1) | 324 | (assoc month (append (memq (assoc 1 (chinese-year g-year)) |
| 164 | (next-month (chinese-new-moon-on-or-after (1+ new-year))) | 325 | (chinese-year g-year)) |
| 165 | (next-sign (chinese-zodiac-sign-on-or-after | 326 | (chinese-year (1+ g-year)))))))) |
| 166 | (1+ (chinese-zodiac-sign-on-or-after current-month)))) | ||
| 167 | (had-leap-month nil)) | ||
| 168 | (while (< current-month-number month) | ||
| 169 | ;; current-month < next-month <= next-sign | ||
| 170 | (setq current-month next-month) | ||
| 171 | (setq next-month (chinese-new-moon-on-or-after (1+ current-month))) | ||
| 172 | (if (and (<= next-month next-sign) (not had-leap-month)) | ||
| 173 | (progn;; leap month | ||
| 174 | (setq current-month-number (+ current-month-number 0.5)) | ||
| 175 | (setq had-leap-month t)) | ||
| 176 | (setq current-month-number (floor (1+ current-month-number))) | ||
| 177 | (setq next-sign (chinese-zodiac-sign-on-or-after (1+ next-sign))))) | ||
| 178 | (+ current-month (1- day)))) | ||
| 179 | 327 | ||
| 180 | (defun calendar-chinese-from-absolute (date) | 328 | (defun calendar-chinese-from-absolute (date) |
| 181 | "Compute Chinese date (cycle year month day) corresponding to absolute DATE. | 329 | "Compute Chinese date (cycle year month day) corresponding to absolute DATE. |
| 182 | The absolute date is the number of days elapsed since the (imaginary) | 330 | The absolute date is the number of days elapsed since the (imaginary) |
| 183 | Gregorian date Sunday, December 31, 1 BC." | 331 | Gregorian date Sunday, December 31, 1 BC." |
| 184 | (let* ((greg-date (calendar-gregorian-from-absolute date)) | 332 | (let* ((g-year (extract-calendar-year |
| 185 | (greg-year (1- (extract-calendar-year greg-date))) | 333 | (calendar-gregorian-from-absolute date))) |
| 186 | (greg-year | 334 | (chinese-year (+ g-year 2695)) |
| 187 | (+ greg-year | 335 | (list (append (chinese-year (1- g-year)) |
| 188 | (calendar-sum y greg-year | 336 | (chinese-year g-year) |
| 189 | (>= date (chinese-new-year (1+ y))) 1)) ) | 337 | (chinese-year (1+ g-year))))) |
| 190 | (chinese-year (+ greg-year 2697)) | 338 | (while (<= (cdr (car (cdr list))) date) |
| 191 | (cycle (/ (1- chinese-year) 60)) ;; previous cycles | 339 | (if (= 1 (car (car (cdr list)))) |
| 192 | (year (calendar-mod chinese-year 60));; years this cycle | 340 | (setq chinese-year (1+ chinese-year))) |
| 193 | (current-month (chinese-new-year greg-year)) | 341 | (setq list (cdr list))) |
| 194 | (month 1) | 342 | (list (/ (1- chinese-year) 60) |
| 195 | (next-month (chinese-new-moon-on-or-after (1+ current-month))) | 343 | (calendar-mod chinese-year 60) |
| 196 | (next-sign (chinese-zodiac-sign-on-or-after | 344 | (car (car list)) |
| 197 | (1+ (chinese-zodiac-sign-on-or-after current-month)))) | 345 | (1+ (- date (cdr (car list))))))) |
| 198 | (had-leap-month nil)) | ||
| 199 | (while (<= next-month date) | ||
| 200 | ;; current-month < next-month <= next-sign | ||
| 201 | (setq current-month next-month) | ||
| 202 | (setq next-month (chinese-new-moon-on-or-after (1+ current-month))) | ||
| 203 | (if (and (<= next-month next-sign) (not had-leap-month)) | ||
| 204 | (progn;; leap month | ||
| 205 | (setq month (+ month 0.5)) | ||
| 206 | (setq had-leap-month t)) | ||
| 207 | (setq month (floor (1+ month))) | ||
| 208 | (setq next-sign (chinese-zodiac-sign-on-or-after (1+ next-sign))))) | ||
| 209 | (list cycle year month (1+ (- date current-month))))) | ||
| 210 | |||
| 211 | (defun chinese-new-year (year) | ||
| 212 | "The absolute date of Chinese New Year in Gregorian YEAR." | ||
| 213 | (let* ((last-solstice (chinese-zodiac-sign-on-or-after | ||
| 214 | (calendar-absolute-from-gregorian | ||
| 215 | (list 12 15 (1- year))))) | ||
| 216 | (twelfth-new-moon;; twelfth month of previous year | ||
| 217 | (chinese-new-moon-on-or-after (1+ last-solstice))) | ||
| 218 | (thirteenth-new-moon;; maybe leap month, maybe New Year | ||
| 219 | (chinese-new-moon-on-or-after (1+ twelfth-new-moon))) | ||
| 220 | (fourteenth-new-moon;; maybe New Year, maybe second month | ||
| 221 | (chinese-new-moon-on-or-after (1+ thirteenth-new-moon))) | ||
| 222 | (next-solstice (chinese-zodiac-sign-on-or-after | ||
| 223 | (calendar-absolute-from-gregorian (list 12 15 year)))) | ||
| 224 | (new-moons (+ 3 (calendar-sum m 0 | ||
| 225 | (< (chinese-new-moon-on-or-after | ||
| 226 | (+ fourteenth-new-moon (* 29 m))) | ||
| 227 | next-solstice) | ||
| 228 | 1)))) | ||
| 229 | (if (and (= new-moons 14) | ||
| 230 | (< (chinese-zodiac-sign-on-or-after | ||
| 231 | (calendar-absolute-from-gregorian (list 2 15 year))) | ||
| 232 | thirteenth-new-moon) | ||
| 233 | (<= fourteenth-new-moon | ||
| 234 | (chinese-zodiac-sign-on-or-after | ||
| 235 | (calendar-absolute-from-gregorian (list 3 15 year))))) | ||
| 236 | fourteeth-new-moon | ||
| 237 | thirteenth-new-moon))) | ||
| 238 | 346 | ||
| 239 | (defun holiday-chinese-new-year () | 347 | (defun holiday-chinese-new-year () |
| 240 | "Date of Chinese New Year." | 348 | "Date of Chinese New Year." |
| @@ -244,7 +352,7 @@ Gregorian date Sunday, December 31, 1 BC." | |||
| 244 | (if (< m 5) | 352 | (if (< m 5) |
| 245 | (let ((chinese-new-year | 353 | (let ((chinese-new-year |
| 246 | (calendar-gregorian-from-absolute | 354 | (calendar-gregorian-from-absolute |
| 247 | (chinese-new-year y)))) | 355 | (cdr (assoc 1 (chinese-year y)))))) |
| 248 | (if (calendar-date-is-visible-p chinese-new-year) | 356 | (if (calendar-date-is-visible-p chinese-new-year) |
| 249 | (list (list chinese-new-year | 357 | (list (list chinese-new-year |
| 250 | (format "Chinese New Year (%s-%s)" | 358 | (format "Chinese New Year (%s-%s)" |
| @@ -266,9 +374,8 @@ Defaults to today's date if DATE is not given." | |||
| 266 | (this-month (calendar-absolute-from-chinese | 374 | (this-month (calendar-absolute-from-chinese |
| 267 | (list cycle year month 1))) | 375 | (list cycle year month 1))) |
| 268 | (next-month (calendar-absolute-from-chinese | 376 | (next-month (calendar-absolute-from-chinese |
| 269 | (list cycle year (1+ month) 1))) | 377 | (list cycle year (1+ (floor month)) 1))) |
| 270 | (month (floor month)) | 378 | (m-cycle (% (+ (* year 5) (floor month)) 60))) |
| 271 | (m-cycle (% (+ (* year 5) month) 60))) | ||
| 272 | (format "Cycle %s, year %s (%s-%s), %smonth %s, day %s (%s-%s)" | 379 | (format "Cycle %s, year %s (%s-%s), %smonth %s, day %s (%s-%s)" |
| 273 | cycle | 380 | cycle |
| 274 | year | 381 | year |
| @@ -279,7 +386,7 @@ Defaults to today's date if DATE is not given." | |||
| 279 | (if (< 30 (- next-month this-month)) | 386 | (if (< 30 (- next-month this-month)) |
| 280 | "first " | 387 | "first " |
| 281 | "")) | 388 | "")) |
| 282 | month | 389 | (floor month) |
| 283 | day | 390 | day |
| 284 | (aref chinese-calendar-celestial-stem (% (+ a-date 4) 10)) | 391 | (aref chinese-calendar-celestial-stem (% (+ a-date 4) 10)) |
| 285 | (aref chinese-calendar-terrestrial-branch (% (+ a-date 2) 12))))) | 392 | (aref chinese-calendar-terrestrial-branch (% (+ a-date 2) 12))))) |
| @@ -299,20 +406,68 @@ Echo Chinese date unless NOECHO is t." | |||
| 299 | (calendar-absolute-from-gregorian | 406 | (calendar-absolute-from-gregorian |
| 300 | (calendar-current-date)))) | 407 | (calendar-current-date)))) |
| 301 | (cycle (calendar-read | 408 | (cycle (calendar-read |
| 302 | "Cycle number (>44): " | 409 | "Chinese calendar cycle number (>44): " |
| 303 | '(lambda (x) (> x 44)) | 410 | '(lambda (x) (> x 44)) |
| 304 | (int-to-string (car c)))) | 411 | (int-to-string (car c)))) |
| 305 | (year (calendar-read | 412 | (year (calendar-read |
| 306 | "Year in cycle (1..60): " | 413 | "Year in Chinese cycle (1..60): " |
| 307 | '(lambda (x) (and (<= 1 x) (<= x 60))) | 414 | '(lambda (x) (and (<= 1 x) (<= x 60))) |
| 308 | (int-to-string (car (cdr c))))) | 415 | (int-to-string (car (cdr c))))) |
| 309 | (month (read-minibuffer "Month: ")) | 416 | (month-list (make-chinese-month-assoc-list |
| 310 | (day (read-minibuffer "Day: "))) | 417 | (chinese-months cycle year))) |
| 418 | (month (cdr (assoc | ||
| 419 | (completing-read "Chinese calendar month: " | ||
| 420 | month-list nil t) | ||
| 421 | month-list))) | ||
| 422 | (last (if (= month | ||
| 423 | (car (cdr (cdr | ||
| 424 | (calendar-chinese-from-absolute | ||
| 425 | (+ 29 | ||
| 426 | (calendar-absolute-from-chinese | ||
| 427 | (list cycle year month 1)))))))) | ||
| 428 | 30 | ||
| 429 | 29)) | ||
| 430 | (day (calendar-read | ||
| 431 | (format "Chinese calendar day (1-%d): " last) | ||
| 432 | '(lambda (x) (and (<= 1 x) (<= x last)))))) | ||
| 311 | (list (list cycle year month day)))) | 433 | (list (list cycle year month day)))) |
| 312 | (calendar-goto-date (calendar-gregorian-from-absolute | 434 | (calendar-goto-date (calendar-gregorian-from-absolute |
| 313 | (calendar-absolute-from-chinese date))) | 435 | (calendar-absolute-from-chinese date))) |
| 314 | (or noecho (calendar-print-chinese-date))) | 436 | (or noecho (calendar-print-chinese-date))) |
| 315 | 437 | ||
| 438 | (defun chinese-months (c y) | ||
| 439 | "A list of the months in cycle C, year Y of the Chinese calendar." | ||
| 440 | (let* ((l (memq 1 (append | ||
| 441 | (mapcar '(lambda (x) | ||
| 442 | (car x)) | ||
| 443 | (chinese-year (extract-calendar-year | ||
| 444 | (calendar-gregorian-from-absolute | ||
| 445 | (calendar-absolute-from-chinese | ||
| 446 | (list c y 1 1)))))) | ||
| 447 | (mapcar '(lambda (x) | ||
| 448 | (if (> (car x) 11) (car x))) | ||
| 449 | (chinese-year (extract-calendar-year | ||
| 450 | (calendar-gregorian-from-absolute | ||
| 451 | (calendar-absolute-from-chinese | ||
| 452 | (list (if (= y 60) (1+ c) c) | ||
| 453 | (if (= y 60) 1 y) | ||
| 454 | 1 1)))))))))) | ||
| 455 | l)) | ||
| 456 | |||
| 457 | (defun make-chinese-month-assoc-list (l) | ||
| 458 | "Make list of months L into an assoc list." | ||
| 459 | (if (and l (car l)) | ||
| 460 | (if (and (cdr l) (car (cdr l))) | ||
| 461 | (if (= (car l) (floor (car (cdr l)))) | ||
| 462 | (append | ||
| 463 | (list (cons (format "%s (first)" (car l)) (car l)) | ||
| 464 | (cons (format "%s (second)" (car l)) (car (cdr l)))) | ||
| 465 | (make-chinese-month-assoc-list (cdr (cdr l)))) | ||
| 466 | (append | ||
| 467 | (list (cons (int-to-string (car l)) (car l))) | ||
| 468 | (make-chinese-month-assoc-list (cdr l)))) | ||
| 469 | (list (cons (int-to-string (car l)) (car l)))))) | ||
| 470 | |||
| 316 | (defun diary-chinese-date () | 471 | (defun diary-chinese-date () |
| 317 | "Chinese calendar equivalent of date diary entry." | 472 | "Chinese calendar equivalent of date diary entry." |
| 318 | (format "Chinese date: %s" (calendar-chinese-date-string date))) | 473 | (format "Chinese date: %s" (calendar-chinese-date-string date))) |