diff options
| author | Jay Belanger | 2012-11-17 15:30:43 -0600 |
|---|---|---|
| committer | Jay Belanger | 2012-11-17 15:30:43 -0600 |
| commit | c9f618db44110a48efdfe166ddc43ce0cb787852 (patch) | |
| tree | 1a05bca6d9f5982bb6bf7d0c8f10e0661ea5946e | |
| parent | 3804f7bc781ab815435520e2600215377336dc86 (diff) | |
| download | emacs-c9f618db44110a48efdfe166ddc43ce0cb787852.tar.gz emacs-c9f618db44110a48efdfe166ddc43ce0cb787852.zip | |
* calc/calc.el (calc-gregorian-switch): New variable.
* calc/calc-forms.el (math-day-in-year, math-dt-before-p)
(math-absolute-from-gregorian-dt, math-absolute-from-julian-dt)
(math-date-to-julian-dt, math-date-to-gregorian-dt): New functions.
(math-leap-year-p): Add option to distinguish between Julian
and Gregorian calendars.
(math-day-number): Use `math-day-in-year' to do the computations.
(math-absolute-from-dt): Rename from `math-absolute-from-date'.
Use `math-absolute-from-gregorian' and `math-absolute-from-julian'
to do the computations.
(math-date-to-dt): Use `math-date-to-julian-dt' and `math-date-to-gregorian-dt'
to do the computations.
(calcFunc-weekday, math-format-date-part): Use the new version of the DATE to
determine the weekday.
(calcFunc-newmonth, calcFunc-newyear): Use `calc-gregorian-switch' when necessary.
| -rw-r--r-- | lisp/ChangeLog | 20 | ||||
| -rw-r--r-- | lisp/calc/calc-forms.el | 323 | ||||
| -rw-r--r-- | lisp/calc/calc.el | 44 |
3 files changed, 313 insertions, 74 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 135ee569aa4..c9c879b5e88 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,23 @@ | |||
| 1 | 2012-11-17 Jay Belanger <jay.p.belanger@gmail.com> | ||
| 2 | |||
| 3 | * calc/calc.el (calc-gregorian-switch): New variable. | ||
| 4 | |||
| 5 | * calc/calc-forms.el (math-day-in-year, math-dt-before-p) | ||
| 6 | (math-absolute-from-gregorian-dt, math-absolute-from-julian-dt) | ||
| 7 | (math-date-to-julian-dt, math-date-to-gregorian-dt): New functions. | ||
| 8 | (math-leap-year-p): Add option to distinguish between Julian | ||
| 9 | and Gregorian calendars. | ||
| 10 | (math-day-number): Use `math-day-in-year' to do the computations. | ||
| 11 | (math-absolute-from-dt): Rename from `math-absolute-from-date'. | ||
| 12 | Use `math-absolute-from-gregorian' and `math-absolute-from-julian' | ||
| 13 | to do the computations. | ||
| 14 | (math-date-to-dt): Use `math-date-to-julian-dt' and | ||
| 15 | `math-date-to-gregorian-dt' to do the computations. | ||
| 16 | (calcFunc-weekday, math-format-date-part): Use the new version of | ||
| 17 | the DATE to determine the weekday. | ||
| 18 | (calcFunc-newmonth, calcFunc-newyear): Use `calc-gregorian-switch' | ||
| 19 | when necessary. | ||
| 20 | |||
| 1 | 2012-11-17 Eli Zaretskii <eliz@gnu.org> | 21 | 2012-11-17 Eli Zaretskii <eliz@gnu.org> |
| 2 | 22 | ||
| 3 | * term/w32-win.el (w32-handle-dropped-file): Use 'file://' only on | 23 | * term/w32-win.el (w32-handle-dropped-file): Use 'file://' only on |
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el index bd748158d66..4573377745c 100644 --- a/lisp/calc/calc-forms.el +++ b/lisp/calc/calc-forms.el | |||
| @@ -369,17 +369,67 @@ | |||
| 369 | 369 | ||
| 370 | ;;; Some of these functions are adapted from Edward Reingold's "calendar.el". | 370 | ;;; Some of these functions are adapted from Edward Reingold's "calendar.el". |
| 371 | ;;; These versions are rewritten to use arbitrary-size integers. | 371 | ;;; These versions are rewritten to use arbitrary-size integers. |
| 372 | ;;; The Julian calendar is used up to 9/2/1752, after which the Gregorian | ||
| 373 | ;;; calendar is used; the first day after 9/2/1752 is 9/14/1752. | ||
| 374 | 372 | ||
| 375 | ;;; A numerical date is the number of days since midnight on | 373 | ;;; A numerical date is the number of days since midnight on |
| 376 | ;;; the morning of January 1, 1 A.D. If the date is a non-integer, | 374 | ;;; the morning of December 31, 1 B.C. Emacs's calendar refers to such |
| 377 | ;;; it represents a specific date and time. | 375 | ;;; a date as an absolute date, some function names also use that |
| 376 | ;;; terminology. If the date is a non-integer, it represents a specific date and time. | ||
| 378 | ;;; A "dt" is a list of the form, (year month day), corresponding to | 377 | ;;; A "dt" is a list of the form, (year month day), corresponding to |
| 379 | ;;; an integer code, or (year month day hour minute second), corresponding | 378 | ;;; an integer code, or (year month day hour minute second), corresponding |
| 380 | ;;; to a non-integer code. | 379 | ;;; to a non-integer code. |
| 381 | 380 | ||
| 381 | (defun math-date-to-gregorian-dt (date) | ||
| 382 | "Return the day (YEAR MONTH DAY) in the Gregorian calendar. | ||
| 383 | DATE is the number of days since December 31, -1 in the Gregorian calendar." | ||
| 384 | (let* ((month 1) | ||
| 385 | day | ||
| 386 | (year (math-quotient (math-add date (if (Math-lessp date 711859) | ||
| 387 | 365 ; for speed, we take | ||
| 388 | -108)) ; >1950 as a special case | ||
| 389 | (if (math-negp date) 366 365))) | ||
| 390 | ; this result may be an overestimate | ||
| 391 | temp) | ||
| 392 | (while (Math-lessp date (setq temp (math-absolute-from-gregorian-dt year 1 1))) | ||
| 393 | (setq year (math-add year -1))) | ||
| 394 | (if (eq year 0) (setq year -1)) | ||
| 395 | (setq date (1+ (math-sub date temp))) | ||
| 396 | (setq temp | ||
| 397 | (if (math-leap-year-p year) | ||
| 398 | [1 32 61 92 122 153 183 214 245 275 306 336 999] | ||
| 399 | [1 32 60 91 121 152 182 213 244 274 305 335 999])) | ||
| 400 | (while (>= date (aref temp month)) | ||
| 401 | (setq month (1+ month))) | ||
| 402 | (setq day (1+ (- date (aref temp (1- month))))) | ||
| 403 | (list year month day))) | ||
| 404 | |||
| 405 | (defun math-date-to-julian-dt (date) | ||
| 406 | "Return the day (YEAR MONTH DAY) in the Julian calendar. | ||
| 407 | DATE is the number of days since December 31, -1 in the Gregorian calendar." | ||
| 408 | (let* ((month 1) | ||
| 409 | day | ||
| 410 | (year (math-quotient (math-add date (if (Math-lessp date 711859) | ||
| 411 | 365 ; for speed, we take | ||
| 412 | -108)) ; >1950 as a special case | ||
| 413 | (if (math-negp date) 366 365))) | ||
| 414 | ; this result may be an overestimate | ||
| 415 | temp) | ||
| 416 | (while (Math-lessp date (setq temp (math-absolute-from-julian-dt year 1 1))) | ||
| 417 | (setq year (math-add year -1))) | ||
| 418 | (if (eq year 0) (setq year -1)) | ||
| 419 | (setq date (1+ (math-sub date temp))) | ||
| 420 | (setq temp | ||
| 421 | (if (math-leap-year-p year t) | ||
| 422 | [1 32 61 92 122 153 183 214 245 275 306 336 999] | ||
| 423 | [1 32 60 91 121 152 182 213 244 274 305 335 999])) | ||
| 424 | (while (>= date (aref temp month)) | ||
| 425 | (setq month (1+ month))) | ||
| 426 | (setq day (1+ (- date (aref temp (1- month))))) | ||
| 427 | (list year month day))) | ||
| 428 | |||
| 382 | (defun math-date-to-dt (value) | 429 | (defun math-date-to-dt (value) |
| 430 | "Return the day and time of VALUE. | ||
| 431 | The integer part of VALUE is the number of days since Dec 31, -1 | ||
| 432 | in the Gregorian calendar and the remaining part determines the time." | ||
| 383 | (if (eq (car-safe value) 'date) | 433 | (if (eq (car-safe value) 'date) |
| 384 | (setq value (nth 1 value))) | 434 | (setq value (nth 1 value))) |
| 385 | (or (math-realp value) | 435 | (or (math-realp value) |
| @@ -387,32 +437,21 @@ | |||
| 387 | (let* ((parts (math-date-parts value)) | 437 | (let* ((parts (math-date-parts value)) |
| 388 | (date (car parts)) | 438 | (date (car parts)) |
| 389 | (time (nth 1 parts)) | 439 | (time (nth 1 parts)) |
| 390 | (month 1) | 440 | (dt (if (and calc-gregorian-switch |
| 391 | day | 441 | (Math-lessp value |
| 392 | (year (math-quotient (math-add date (if (Math-lessp date 711859) | 442 | (or |
| 393 | 365 ; for speed, we take | 443 | (nth 3 calc-gregorian-switch) |
| 394 | -108)) ; >1950 as a special case | 444 | (apply 'math-absolute-from-gregorian-dt calc-gregorian-switch)) |
| 395 | (if (math-negp value) 366 365))) | 445 | )) |
| 396 | ; this result may be an overestimate | 446 | (math-date-to-julian-dt value) |
| 397 | temp) | 447 | (math-date-to-gregorian-dt value)))) |
| 398 | (while (Math-lessp date (setq temp (math-absolute-from-date year 1 1))) | ||
| 399 | (setq year (math-add year -1))) | ||
| 400 | (if (eq year 0) (setq year -1)) | ||
| 401 | (setq date (1+ (math-sub date temp))) | ||
| 402 | (and (eq year 1752) (>= date 247) | ||
| 403 | (setq date (+ date 11))) | ||
| 404 | (setq temp (if (math-leap-year-p year) | ||
| 405 | [1 32 61 92 122 153 183 214 245 275 306 336 999] | ||
| 406 | [1 32 60 91 121 152 182 213 244 274 305 335 999])) | ||
| 407 | (while (>= date (aref temp month)) | ||
| 408 | (setq month (1+ month))) | ||
| 409 | (setq day (1+ (- date (aref temp (1- month))))) | ||
| 410 | (if (math-integerp value) | 448 | (if (math-integerp value) |
| 411 | (list year month day) | 449 | dt |
| 412 | (list year month day | 450 | (append dt |
| 413 | (/ time 3600) | 451 | (list |
| 414 | (% (/ time 60) 60) | 452 | (/ time 3600) |
| 415 | (math-add (% time 60) (nth 2 parts)))))) | 453 | (% (/ time 60) 60) |
| 454 | (math-add (% time 60) (nth 2 parts))))))) | ||
| 416 | 455 | ||
| 417 | (defun math-dt-to-date (dt) | 456 | (defun math-dt-to-date (dt) |
| 418 | (or (integerp (nth 1 dt)) | 457 | (or (integerp (nth 1 dt)) |
| @@ -423,7 +462,7 @@ | |||
| 423 | (math-reject-arg (nth 2 dt) 'fixnump)) | 462 | (math-reject-arg (nth 2 dt) 'fixnump)) |
| 424 | (if (or (< (nth 2 dt) 1) (> (nth 2 dt) 31)) | 463 | (if (or (< (nth 2 dt) 1) (> (nth 2 dt) 31)) |
| 425 | (math-reject-arg (nth 2 dt) "Day value is out of range")) | 464 | (math-reject-arg (nth 2 dt) "Day value is out of range")) |
| 426 | (let ((date (math-absolute-from-date (car dt) (nth 1 dt) (nth 2 dt)))) | 465 | (let ((date (math-absolute-from-dt (car dt) (nth 1 dt) (nth 2 dt)))) |
| 427 | (if (nth 3 dt) | 466 | (if (nth 3 dt) |
| 428 | (math-add (math-float date) | 467 | (math-add (math-float date) |
| 429 | (math-div (math-add (+ (* (nth 3 dt) 3600) | 468 | (math-div (math-add (+ (* (nth 3 dt) 3600) |
| @@ -446,8 +485,12 @@ | |||
| 446 | (defun math-this-year () | 485 | (defun math-this-year () |
| 447 | (nth 5 (decode-time))) | 486 | (nth 5 (decode-time))) |
| 448 | 487 | ||
| 449 | (defun math-leap-year-p (year) | 488 | (defun math-leap-year-p (year &optional julian) |
| 450 | (if (Math-lessp year 1752) | 489 | "Non-nil if YEAR is a leap year. |
| 490 | If JULIAN is non-nil, then use the criterion for leap years | ||
| 491 | in the Julian calendar, otherwise use the criterion in the | ||
| 492 | Gregorian calendar." | ||
| 493 | (if julian | ||
| 451 | (if (math-negp year) | 494 | (if (math-negp year) |
| 452 | (= (math-imod (math-neg year) 4) 1) | 495 | (= (math-imod (math-neg year) 4) 1) |
| 453 | (= (math-imod year 4) 0)) | 496 | (= (math-imod year 4) 0)) |
| @@ -460,39 +503,100 @@ | |||
| 460 | 29 | 503 | 29 |
| 461 | (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month)))) | 504 | (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month)))) |
| 462 | 505 | ||
| 463 | (defun math-day-number (year month day) | 506 | (defun math-day-in-year (year month day &optional julian) |
| 507 | "Return the number of days of the year up to YEAR MONTH DAY. | ||
| 508 | The count includes the given date. | ||
| 509 | If JULIAN is non-nil, use the Julian calendar, otherwise | ||
| 510 | use the Gregorian calendar." | ||
| 464 | (let ((day-of-year (+ day (* 31 (1- month))))) | 511 | (let ((day-of-year (+ day (* 31 (1- month))))) |
| 465 | (if (> month 2) | 512 | (if (> month 2) |
| 466 | (progn | 513 | (progn |
| 467 | (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10))) | 514 | (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10))) |
| 468 | (if (math-leap-year-p year) | 515 | (if (math-leap-year-p year julian) |
| 469 | (setq day-of-year (1+ day-of-year))))) | 516 | (setq day-of-year (1+ day-of-year))))) |
| 470 | (and (eq year 1752) | ||
| 471 | (or (> month 9) | ||
| 472 | (and (= month 9) (>= day 14))) | ||
| 473 | (setq day-of-year (- day-of-year 11))) | ||
| 474 | day-of-year)) | 517 | day-of-year)) |
| 475 | 518 | ||
| 476 | (defun math-absolute-from-date (year month day) | 519 | (defun math-day-number (year month day) |
| 520 | "Return the number of days of the year up to YEAR MONTH DAY. | ||
| 521 | The count includes the given date." | ||
| 522 | (if calc-gregorian-switch | ||
| 523 | (cond ((math-equalp year (nth 0 calc-gregorian-switch)) | ||
| 524 | (1+ | ||
| 525 | (- (math-absolute-from-dt year month day) | ||
| 526 | (math-absolute-from-dt year 1 1)))) | ||
| 527 | ((Math-lessp year (nth 0 calc-gregorian-switch)) | ||
| 528 | (math-day-in-year year month day t)) | ||
| 529 | (t | ||
| 530 | (math-day-in-year year month day))) | ||
| 531 | (math-day-in-year year month day))) | ||
| 532 | |||
| 533 | (defun math-dt-before-p (dt1 dt2) | ||
| 534 | "Non-nil if DT1 occurs before DT2. | ||
| 535 | A DT is a list of the form (YEAR MONTH DAY)." | ||
| 536 | (or (Math-lessp (nth 0 dt1) (nth 0 dt2)) | ||
| 537 | (and (equal (nth 0 dt1) (nth 0 dt2)) | ||
| 538 | (or (< (nth 1 dt1) (nth 1 dt2)) | ||
| 539 | (and (= (nth 1 dt1) (nth 1 dt2)) | ||
| 540 | (< (nth 2 dt1) (nth 2 dt2))))))) | ||
| 541 | |||
| 542 | (defun math-absolute-from-gregorian-dt (year month day) | ||
| 543 | "Return the DATE of the day given by the Gregorian day YEAR MONTH DAY. | ||
| 544 | Recall that DATE is the number of days since December 31, -1 | ||
| 545 | in the Gregorian calendar." | ||
| 477 | (if (eq year 0) (setq year -1)) | 546 | (if (eq year 0) (setq year -1)) |
| 478 | (let ((yearm1 (math-sub year 1))) | 547 | (let ((yearm1 (math-sub year 1))) |
| 479 | (math-sub (math-add (math-day-number year month day) | 548 | (math-sub |
| 480 | (math-add (math-mul 365 yearm1) | 549 | ;; Add the number of days of the year and the numbers of days |
| 481 | (if (math-posp year) | 550 | ;; in the previous years (leap year days to be added separately) |
| 482 | (math-quotient yearm1 4) | 551 | (math-add (math-day-in-year year month day) |
| 483 | (math-sub 365 | 552 | (math-add (math-mul 365 yearm1) |
| 484 | (math-quotient (math-sub 3 year) | 553 | ;; Add the number of Julian leap years |
| 485 | 4))))) | 554 | (if (math-posp year) |
| 486 | (if (or (Math-lessp year 1753) | 555 | (math-quotient yearm1 4) |
| 487 | (and (eq year 1752) (<= month 9))) | 556 | (math-sub 365 |
| 488 | 1 | 557 | (math-quotient (math-sub 3 year) |
| 489 | (let ((correction (math-mul (math-quotient yearm1 100) 3))) | 558 | 4))))) |
| 490 | (let ((res (math-idivmod correction 4))) | 559 | ;; Subtract the number of Julian leap years which are not |
| 491 | (math-add (if (= (cdr res) 0) | 560 | ;; Gregorian leap years. In C=4N+r centuries, there will |
| 492 | -1 | 561 | ;; be 3N+r of these days. The following will compute |
| 493 | 0) | 562 | ;; 3N+r. |
| 494 | (car res)))))))) | 563 | (let* ((correction (math-mul (math-quotient yearm1 100) 3)) |
| 495 | 564 | (res (math-idivmod correction 4))) | |
| 565 | (math-add (if (= (cdr res) 0) | ||
| 566 | 0 | ||
| 567 | 1) | ||
| 568 | (car res)))))) | ||
| 569 | |||
| 570 | (defun math-absolute-from-julian-dt (year month day) | ||
| 571 | "Return the DATE of the day given by the Julian day YEAR MONTH DAY. | ||
| 572 | Recall that DATE is the number of days since December 31, -1 | ||
| 573 | in the Gregorian calendar." | ||
| 574 | (if (eq year 0) (setq year -1)) | ||
| 575 | (let ((yearm1 (math-sub year 1))) | ||
| 576 | (math-sub | ||
| 577 | ;; Add the number of days of the year and the numbers of days | ||
| 578 | ;; in the previous years (leap year days to be added separately) | ||
| 579 | (math-add (math-day-in-year year month day) | ||
| 580 | (math-add (math-mul 365 yearm1) | ||
| 581 | ;; Add the number of Julian leap years | ||
| 582 | (if (math-posp year) | ||
| 583 | (math-quotient yearm1 4) | ||
| 584 | (math-sub 365 | ||
| 585 | (math-quotient (math-sub 3 year) | ||
| 586 | 4))))) | ||
| 587 | ;; Adjustment, since January 1, 1 (Julian) is absolute day -1 | ||
| 588 | 2))) | ||
| 589 | |||
| 590 | (defun math-absolute-from-dt (year month day) | ||
| 591 | "Return the DATE of the day given by the day YEAR MONTH DAY. | ||
| 592 | Recall that DATE is the number of days since December 31, -1 | ||
| 593 | in the Gregorian calendar." | ||
| 594 | (if (and calc-gregorian-switch | ||
| 595 | ;; The next few lines determine if the given date | ||
| 596 | ;; occurs before the switch to the Gregorian calendar. | ||
| 597 | (math-dt-before-p (list year month day) calc-gregorian-switch)) | ||
| 598 | (math-absolute-from-julian-dt year month day) | ||
| 599 | (math-absolute-from-gregorian-dt year month day))) | ||
| 496 | 600 | ||
| 497 | ;;; It is safe to redefine these in your init file to use a different | 601 | ;;; It is safe to redefine these in your init file to use a different |
| 498 | ;;; language. | 602 | ;;; language. |
| @@ -585,8 +689,7 @@ as measured in the integer number of days before January 1 of the year 1AD.") | |||
| 585 | math-fd-year (car math-fd-dt) | 689 | math-fd-year (car math-fd-dt) |
| 586 | math-fd-month (nth 1 math-fd-dt) | 690 | math-fd-month (nth 1 math-fd-dt) |
| 587 | math-fd-day (nth 2 math-fd-dt) | 691 | math-fd-day (nth 2 math-fd-dt) |
| 588 | math-fd-weekday (math-mod | 692 | math-fd-weekday (math-mod (math-floor math-fd-date) 7) |
| 589 | (math-add (math-floor math-fd-date) 6) 7) | ||
| 590 | math-fd-hour (nth 3 math-fd-dt) | 693 | math-fd-hour (nth 3 math-fd-dt) |
| 591 | math-fd-minute (nth 4 math-fd-dt) | 694 | math-fd-minute (nth 4 math-fd-dt) |
| 592 | math-fd-second (nth 5 math-fd-dt)) | 695 | math-fd-second (nth 5 math-fd-dt)) |
| @@ -1098,7 +1201,7 @@ as measured in the integer number of days before January 1 of the year 1AD.") | |||
| 1098 | (setq date (nth 1 date))) | 1201 | (setq date (nth 1 date))) |
| 1099 | (or (math-realp date) | 1202 | (or (math-realp date) |
| 1100 | (math-reject-arg date 'datep)) | 1203 | (math-reject-arg date 'datep)) |
| 1101 | (math-mod (math-add (math-floor date) 6) 7)) | 1204 | (math-mod (math-floor date) 7)) |
| 1102 | 1205 | ||
| 1103 | (defun calcFunc-yearday (date) | 1206 | (defun calcFunc-yearday (date) |
| 1104 | (let ((dt (math-date-to-dt date))) | 1207 | (let ((dt (math-date-to-dt date))) |
| @@ -1298,7 +1401,7 @@ second, the number of seconds offset for daylight savings." | |||
| 1298 | 0))) | 1401 | 0))) |
| 1299 | (rounded-abs-date | 1402 | (rounded-abs-date |
| 1300 | (+ | 1403 | (+ |
| 1301 | (calendar-absolute-from-gregorian | 1404 | (calendar-absolute-from-gregorian |
| 1302 | (list (nth 1 dt) (nth 2 dt) (nth 0 dt))) | 1405 | (list (nth 1 dt) (nth 2 dt) (nth 0 dt))) |
| 1303 | (/ (round (* 60 time)) 60.0 24.0)))) | 1406 | (/ (round (* 60 time)) 60.0 24.0)))) |
| 1304 | (if (dst-in-effect rounded-abs-date) | 1407 | (if (dst-in-effect rounded-abs-date) |
| @@ -1434,28 +1537,100 @@ and ends on the last Sunday of October at 2 a.m." | |||
| 1434 | (and (math-messy-integerp day) (setq day (math-trunc day))) | 1537 | (and (math-messy-integerp day) (setq day (math-trunc day))) |
| 1435 | (or (integerp day) (math-reject-arg day 'fixnump)) | 1538 | (or (integerp day) (math-reject-arg day 'fixnump)) |
| 1436 | (and (or (< day 0) (> day 31)) (math-reject-arg day 'range)) | 1539 | (and (or (< day 0) (> day 31)) (math-reject-arg day 'range)) |
| 1437 | (let ((dt (math-date-to-dt date))) | 1540 | (let* ((dt (math-date-to-dt date)) |
| 1438 | (if (or (= day 0) (> day (math-days-in-month (car dt) (nth 1 dt)))) | 1541 | (dim (math-days-in-month (car dt) (nth 1 dt))) |
| 1439 | (setq day (math-days-in-month (car dt) (nth 1 dt)))) | 1542 | (julian (if calc-gregorian-switch |
| 1440 | (and (eq (car dt) 1752) (= (nth 1 dt) 9) | 1543 | (math-date-to-dt (math-sub |
| 1441 | (if (>= day 14) (setq day (- day 11)))) | 1544 | (or (nth 3 calc-gregorian-switch) |
| 1442 | (list 'date (math-add (math-dt-to-date (list (car dt) (nth 1 dt) 1)) | 1545 | (apply 'math-absolute-from-gregorian-dt calc-gregorian-switch)) |
| 1443 | (1- day))))) | 1546 | 1))))) |
| 1547 | (if (or (= day 0) (> day dim)) | ||
| 1548 | (setq day (1- dim)) | ||
| 1549 | (setq day (1- day))) | ||
| 1550 | ;; Adjust if this occurs near the switch to the Gregorian calendar | ||
| 1551 | (if calc-gregorian-switch | ||
| 1552 | (cond | ||
| 1553 | ((and (math-dt-before-p (list (car dt) (nth 1 dt) 1) calc-gregorian-switch) | ||
| 1554 | (math-dt-before-p julian (list (car dt) (nth 1 dt) 1))) | ||
| 1555 | ;; In this case, CALC-GREGORIAN-SWITCH is the first day of the month | ||
| 1556 | (list 'date | ||
| 1557 | (math-dt-to-date (list (car calc-gregorian-switch) | ||
| 1558 | (nth 1 calc-gregorian-switch) | ||
| 1559 | (if (> (+ (nth 2 calc-gregorian-switch) day) dim) | ||
| 1560 | dim | ||
| 1561 | (+ (nth 2 calc-gregorian-switch) day)))))) | ||
| 1562 | ((and (eq (car dt) (car calc-gregorian-switch)) | ||
| 1563 | (= (nth 1 dt) (nth 1 calc-gregorian-switch))) | ||
| 1564 | ;; In this case, the switch to the Gregorian calendar occurs in the given month | ||
| 1565 | (if (< (+ (nth 2 julian) day) (nth 2 calc-gregorian-switch)) | ||
| 1566 | ;; If the DAYth day occurs before the switch, use it | ||
| 1567 | (list 'date (math-dt-to-date (list (car dt) (nth 1 dt) (1+ day)))) | ||
| 1568 | ;; Otherwise do some computations | ||
| 1569 | (let ((tm (+ day (- (nth 2 calc-gregorian-switch) (nth 2 julian))))) | ||
| 1570 | (list 'date (math-dt-to-date | ||
| 1571 | (list (car dt) | ||
| 1572 | (nth 1 dt) | ||
| 1573 | ;; | ||
| 1574 | (if (> tm dim) dim tm))))))) | ||
| 1575 | ((and (eq (car dt) (car julian)) | ||
| 1576 | (= (nth 1 dt) (nth 1 julian))) | ||
| 1577 | ;; In this case, the current month is truncated because of the switch | ||
| 1578 | ;; to the Gregorian calendar | ||
| 1579 | (list 'date (math-dt-to-date | ||
| 1580 | (list (car dt) | ||
| 1581 | (nth 1 dt) | ||
| 1582 | (if (>= day (nth 2 julian)) | ||
| 1583 | (nth 2 julian) | ||
| 1584 | (1+ day)))))) | ||
| 1585 | (t | ||
| 1586 | ;; The default | ||
| 1587 | (list 'date (math-add (math-dt-to-date (list (car dt) (nth 1 dt) 1)) day)))) | ||
| 1588 | (list 'date (math-add (math-dt-to-date (list (car dt) (nth 1 dt) 1)) day))))) | ||
| 1444 | 1589 | ||
| 1445 | (defun calcFunc-newyear (date &optional day) | 1590 | (defun calcFunc-newyear (date &optional day) |
| 1591 | (if (eq (car-safe date) 'date) (setq date (nth 1 date))) | ||
| 1446 | (or day (setq day 1)) | 1592 | (or day (setq day 1)) |
| 1447 | (and (math-messy-integerp day) (setq day (math-trunc day))) | 1593 | (and (math-messy-integerp day) (setq day (math-trunc day))) |
| 1448 | (or (integerp day) (math-reject-arg day 'fixnump)) | 1594 | (or (integerp day) (math-reject-arg day 'fixnump)) |
| 1449 | (let ((dt (math-date-to-dt date))) | 1595 | (let* ((dt (math-date-to-dt date)) |
| 1596 | (gregbeg (if calc-gregorian-switch | ||
| 1597 | (or (nth 3 calc-gregorian-switch) | ||
| 1598 | (apply 'math-absolute-from-gregorian-dt calc-gregorian-switch)))) | ||
| 1599 | (julianend (if calc-gregorian-switch (math-sub gregbeg 1))) | ||
| 1600 | (julian (if calc-gregorian-switch | ||
| 1601 | (math-date-to-dt julianend)))) | ||
| 1450 | (if (and (>= day 0) (<= day 366)) | 1602 | (if (and (>= day 0) (<= day 366)) |
| 1451 | (let ((max (if (eq (car dt) 1752) 355 | 1603 | (let ((max (if (math-leap-year-p (car dt)) 366 365))) |
| 1452 | (if (math-leap-year-p (car dt)) 366 365)))) | ||
| 1453 | (if (or (= day 0) (> day max)) (setq day max)) | 1604 | (if (or (= day 0) (> day max)) (setq day max)) |
| 1454 | (list 'date (math-add (math-dt-to-date (list (car dt) 1 1)) | 1605 | (if calc-gregorian-switch |
| 1455 | (1- day)))) | 1606 | ;; Now to break this down into cases |
| 1607 | (cond | ||
| 1608 | ((and (math-dt-before-p (list (car dt) 1 1) calc-gregorian-switch) | ||
| 1609 | (math-dt-before-p julian (list (car dt) 1 1))) | ||
| 1610 | ;; In this case, CALC-GREGORIAN-SWITCH is the first day of the year | ||
| 1611 | (list 'date (math-min (math-add gregbeg (1- day)) | ||
| 1612 | (math-dt-to-date (list (car calc-gregorian-switch) 12 31))))) | ||
| 1613 | ((eq (car dt) (car julian)) | ||
| 1614 | ;; In this case, the switch to the Gregorian calendar occurs in the given year | ||
| 1615 | (if (Math-lessp (car julian) (car calc-gregorian-switch)) | ||
| 1616 | ;; Here, the last Julian day is the last day of the year. | ||
| 1617 | (list 'date (math-min (math-add (math-dt-to-date (list (car dt) 1 1)) (1- day)) | ||
| 1618 | julianend)) | ||
| 1619 | ;; Otherwise, just make sure the date doesn't go past the end of the year | ||
| 1620 | (list 'date (math-min (math-add (math-dt-to-date (list (car dt) 1 1)) (1- day)) | ||
| 1621 | (math-dt-to-date (list (car dt) 12 31)))))) | ||
| 1622 | (t | ||
| 1623 | (list 'date (math-add (math-dt-to-date (list (car dt) 1 1)) | ||
| 1624 | (1- day))))) | ||
| 1625 | (list 'date (math-add (math-dt-to-date (list (car dt) 1 1)) | ||
| 1626 | (1- day))))) | ||
| 1456 | (if (and (>= day -12) (<= day -1)) | 1627 | (if (and (>= day -12) (<= day -1)) |
| 1457 | (list 'date (math-dt-to-date (list (car dt) (- day) 1))) | 1628 | (if (and calc-gregorian-switch |
| 1458 | (math-reject-arg day 'range))))) | 1629 | (math-dt-before-p (list (car dt) (- day) 1) calc-gregorian-switch) |
| 1630 | (math-dt-before-p julian (list (car dt) (- day) 1))) | ||
| 1631 | (list 'date gregbeg) | ||
| 1632 | (list 'date (math-dt-to-date (list (car dt) (- day) 1)))) | ||
| 1633 | (math-reject-arg day 'range))))) | ||
| 1459 | 1634 | ||
| 1460 | (defun calcFunc-incmonth (date &optional step) | 1635 | (defun calcFunc-incmonth (date &optional step) |
| 1461 | (or step (setq step 1)) | 1636 | (or step (setq step 1)) |
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index f1643b10a76..2d75e897d9b 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el | |||
| @@ -464,6 +464,50 @@ to be identified as that note." | |||
| 464 | :type 'string | 464 | :type 'string |
| 465 | :group 'calc) | 465 | :group 'calc) |
| 466 | 466 | ||
| 467 | ;; Dates that are built-in options for `calc-gregorian-switch' should be | ||
| 468 | ;; (YEAR MONTH DAY math-date-from-gregorian-dt(YEAR MONTH DAY)) for speed. | ||
| 469 | (defcustom calc-gregorian-switch nil | ||
| 470 | "The first day the Gregorian calendar is used by Calc's date forms. | ||
| 471 | This is `nil' (the default) if the Gregorian calendar is the only one used. | ||
| 472 | Otherwise, it should be a list `(YEAR MONTH DAY)' when Calc begins to use | ||
| 473 | the Gregorian calendar; Calc will use the Julian calendar for earlier dates. | ||
| 474 | The dates in which different regions of the world began to use the | ||
| 475 | Gregorian calendar vary quite a bit, even within a single country. | ||
| 476 | If you want Calc's date forms to switch between the Julian and | ||
| 477 | Gregorian calendar, you can specify the date or choose from several | ||
| 478 | common choices. Some of these choices should be taken with a grain | ||
| 479 | of salt; for example different parts of France changed calendars at | ||
| 480 | different times, and Sweden's change to the Gregorian calendar was | ||
| 481 | complicated. Also, the boundaries of the countries were different at | ||
| 482 | the times of the calendar changes than they are now. | ||
| 483 | The Vatican decided that the Gregorian calendar should take effect | ||
| 484 | on 15 October 1582 (Gregorian), and many Catholic countries made | ||
| 485 | the change then. Great Britian and its colonies had the Gregorian | ||
| 486 | calendar take effect on 14 September 1752 (Gregorian); this includes | ||
| 487 | the United States." | ||
| 488 | :group 'calc | ||
| 489 | :version "24.4" | ||
| 490 | :type '(choice (const :tag "Always use the Gregorian calendar" nil) | ||
| 491 | (const :tag "Great Britian and the US (1752 9 14)" (1752 9 14 639797)) | ||
| 492 | (const :tag "Vatican (1582 10 15)" (1582 10 15 577736)) | ||
| 493 | (const :tag "Czechoslovakia (1584 1 17)" (1584 1 17 578195)) | ||
| 494 | (const :tag "Denmark (1700 3 1)" (1700 3 1 620607)) | ||
| 495 | (const :tag "France (1582 12 20)" (1582 12 20 577802)) | ||
| 496 | (const :tag "Hungary (1587 11 1)" (1587 11 1 579579)) | ||
| 497 | (const :tag "Luxemburg (1582 12 25)" (1582 12 25 577807)) | ||
| 498 | (const :tag "Romania (1919 4 14)" (1919 4 14 700638)) | ||
| 499 | (const :tag "Russia (1918 2 14)" (1918 2 14 700214)) | ||
| 500 | (const :tag "Sweden (1753 3 1)" (1753 3 1 639965)) | ||
| 501 | (const :tag "Switzerland (Catholic) (1584 1 22)" (1584 1 22 578200)) | ||
| 502 | (const :tag "Switzerland (Protestant) (1701 1 12)" (1701 1 12 620924)) | ||
| 503 | (list :tag "(YEAR MONTH DAY)" | ||
| 504 | (integer :tag "Year") | ||
| 505 | (integer :tag "Month (integer)") | ||
| 506 | (integer :tag "Day"))) | ||
| 507 | :set (lambda (symbol value) | ||
| 508 | (set-default symbol value) | ||
| 509 | (setq math-format-date-cache nil))) | ||
| 510 | |||
| 467 | (defface calc-nonselected-face | 511 | (defface calc-nonselected-face |
| 468 | '((t :inherit shadow | 512 | '((t :inherit shadow |
| 469 | :slant italic)) | 513 | :slant italic)) |