aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Belanger2012-11-17 15:30:43 -0600
committerJay Belanger2012-11-17 15:30:43 -0600
commitc9f618db44110a48efdfe166ddc43ce0cb787852 (patch)
tree1a05bca6d9f5982bb6bf7d0c8f10e0661ea5946e
parent3804f7bc781ab815435520e2600215377336dc86 (diff)
downloademacs-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/ChangeLog20
-rw-r--r--lisp/calc/calc-forms.el323
-rw-r--r--lisp/calc/calc.el44
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 @@
12012-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
12012-11-17 Eli Zaretskii <eliz@gnu.org> 212012-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.
383DATE 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.
407DATE 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.
431The integer part of VALUE is the number of days since Dec 31, -1
432in 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.
490If JULIAN is non-nil, then use the criterion for leap years
491in the Julian calendar, otherwise use the criterion in the
492Gregorian 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.
508The count includes the given date.
509If JULIAN is non-nil, use the Julian calendar, otherwise
510use 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.
521The 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.
535A 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.
544Recall that DATE is the number of days since December 31, -1
545in 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.
572Recall that DATE is the number of days since December 31, -1
573in 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.
592Recall that DATE is the number of days since December 31, -1
593in 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.
471This is `nil' (the default) if the Gregorian calendar is the only one used.
472Otherwise, it should be a list `(YEAR MONTH DAY)' when Calc begins to use
473the Gregorian calendar; Calc will use the Julian calendar for earlier dates.
474The dates in which different regions of the world began to use the
475Gregorian calendar vary quite a bit, even within a single country.
476If you want Calc's date forms to switch between the Julian and
477Gregorian calendar, you can specify the date or choose from several
478common choices. Some of these choices should be taken with a grain
479of salt; for example different parts of France changed calendars at
480different times, and Sweden's change to the Gregorian calendar was
481complicated. Also, the boundaries of the countries were different at
482the times of the calendar changes than they are now.
483The Vatican decided that the Gregorian calendar should take effect
484on 15 October 1582 (Gregorian), and many Catholic countries made
485the change then. Great Britian and its colonies had the Gregorian
486calendar take effect on 14 September 1752 (Gregorian); this includes
487the 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))