summaryrefslogtreecommitdiff
path: root/lisp/calc/calc-forms.el
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2019-07-30 17:33:19 +0200
committerMattias EngdegÄrd <mattiase@acm.org>2019-08-06 13:59:28 +0200
commit4ce9c6d0b58bd77bc811d6c1c5caf955a5a0be2f (patch)
treec232b8d99716d4d2c95363f09f27f5093067c63c /lisp/calc/calc-forms.el
parentc676444a43e4634c1f98ec286b5bd9e46b23216b (diff)
downloademacs-4ce9c6d0b58bd77bc811d6c1c5caf955a5a0be2f.tar.gz
Fix various Calc date conversions (bug#36822)
* lisp/calc/calc-forms.el (math-absolute-from-gregorian-dt): Rewrite in a way that I understand, and that actually seems to work. (math-absolute-from-julian-dt): Use Julian, not Gregorian, leap year rules for counting days within a year. (math-julian-date-beginning, math-julian-date-beginning-int): Change constants to be consistent with their doc strings and the code: use Rata Die epoch at Dec 31, 1 BC Gregorian proleptic, not Julian. * doc/misc/calc.texi (Date Forms): Correct difference between Julian Day and Rata Die. * test/lisp/calc/calc-tests.el (calc-test-calendar): New test.
Diffstat (limited to 'lisp/calc/calc-forms.el')
-rw-r--r--lisp/calc/calc-forms.el38
1 files changed, 12 insertions, 26 deletions
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index bdfc0e44ddd..c410ffe449c 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -587,29 +587,15 @@ A DT is a list of the form (YEAR MONTH DAY)."
"Return the DATE of the day given by the Gregorian day YEAR MONTH DAY.
Recall that DATE is the number of days since December 31, -1
in the Gregorian calendar."
- (if (eq year 0) (setq year -1))
- (let ((yearm1 (math-sub year 1)))
- (math-sub
- ;; Add the number of days of the year and the numbers of days
- ;; in the previous years (leap year days to be added separately)
- (math-add (math-day-in-year year month day)
- (math-add (math-mul 365 yearm1)
- ;; Add the number of Julian leap years
- (if (math-posp year)
- (math-quotient yearm1 4)
- (math-sub 365
- (math-quotient (math-sub 3 year)
- 4)))))
- ;; Subtract the number of Julian leap years which are not
- ;; Gregorian leap years. In C=4N+r centuries, there will
- ;; be 3N+r of these days. The following will compute
- ;; 3N+r.
- (let* ((correction (math-mul (math-quotient yearm1 100) 3))
- (res (math-idivmod correction 4)))
- (math-add (if (= (cdr res) 0)
- 0
- 1)
- (car res))))))
+ (when (zerop year) ; Year -1 precedes year 1.
+ (setq year -1))
+ (let* ((y (if (> year 0) year (+ year 1))) ; Astronomical year (with 0).
+ (y1 (- y 1))) ; Previous year.
+ (+ (* y1 365) ; Days up to the previous year...
+ (floor y1 4) ; ... including leap days.
+ (- (floor y1 100))
+ (floor y1 400)
+ (math-day-in-year year month day))))
(defun math-absolute-from-julian-dt (year month day)
"Return the DATE of the day given by the Julian day YEAR MONTH DAY.
@@ -620,7 +606,7 @@ in the Gregorian calendar."
(math-sub
;; Add the number of days of the year and the numbers of days
;; in the previous years (leap year days to be added separately)
- (math-add (math-day-in-year year month day)
+ (math-add (math-day-in-year year month day t)
(math-add (math-mul 365 yearm1)
;; Add the number of Julian leap years
(if (math-posp year)
@@ -714,11 +700,11 @@ in the Gregorian calendar."
(setcdr math-fd-dt nil))
fmt))))
-(defconst math-julian-date-beginning '(float 17214225 -1)
+(defconst math-julian-date-beginning '(float 17214245 -1)
"The beginning of the Julian date calendar,
as measured in the number of days before December 31, 1 BC (Gregorian).")
-(defconst math-julian-date-beginning-int 1721423
+(defconst math-julian-date-beginning-int 1721425
"The beginning of the Julian date calendar,
as measured in the integer number of days before December 31, 1 BC (Gregorian).")