summaryrefslogtreecommitdiff
path: root/lisp/calc/calc-forms.el
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2020-09-30 23:57:27 +0200
committerMattias EngdegÄrd <mattiase@acm.org>2020-10-02 10:35:52 +0200
commit4cb16b6f42ea7ea088fa4134f8fe4ccfec16a56d (patch)
tree618a3b8e1b61b6092fdb81dc7ead79c0794a453e /lisp/calc/calc-forms.el
parentd037a6a2e6f92d793b1d5403dea4c7d3ca70883c (diff)
downloademacs-4cb16b6f42ea7ea088fa4134f8fe4ccfec16a56d.tar.gz
Calc: fix business days calculation (bug43677)
The calculation of business days was broken in 2012 (probably 310e60d9454fe2 or thereabouts) when the date representation changed epoch so that Jan 1, 1 AD became day number 1 instead of 0. Repair this, along with an unrelated bug that prevented arbitrary holiday weekdays from working. Reported by Aaron Zeng. * lisp/calc/calc-forms.el (math-to-business-day) (math-from-business-day): Correct calculation of weekdays using Calc's current (Rata Die) chronology. Modify loop condition to cope with odd sets of holiday weekdays. * test/lisp/calc/calc-tests.el (calc-business-days): New test.
Diffstat (limited to 'lisp/calc/calc-forms.el')
-rw-r--r--lisp/calc/calc-forms.el13
1 files changed, 7 insertions, 6 deletions
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index 5a8f0a38d24..6d70126c098 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -1870,8 +1870,8 @@ and ends on the last Sunday of October at 2 a.m."
(and days (= day (car days))
(setq holiday t)))
(let* ((weekdays (nth 3 math-holidays-cache))
- (weeks (1- (/ (+ day 6) 7)))
- (wkday (- day 1 (* weeks 7))))
+ (weeks (/ day 7))
+ (wkday (mod day 7))) ; Day of week: 0=Sunday, 6=Saturday
(setq delta (+ delta (* weeks (length weekdays))))
(while (and weekdays (< (car weekdays) wkday))
(setq weekdays (cdr weekdays)
@@ -1905,14 +1905,15 @@ and ends on the last Sunday of October at 2 a.m."
(setq delta (1+ delta)))
(setq day (+ day delta)))
(let* ((weekdays (nth 3 math-holidays-cache))
- (bweek (- 7 (length weekdays)))
- (weeks (1- (/ (+ day (1- bweek)) bweek)))
- (wkday (- day 1 (* weeks bweek)))
+ (bweek (- 7 (length weekdays))) ; Business days in a week, 1..7.
+ (weeks (/ day bweek)) ; Whole weeks.
+ (wkday (mod day bweek)) ; Business day in last week, 0..bweek-1
(w 0))
(setq day (+ day (* weeks (length weekdays))))
+ ;; Add business days in the last week; `w' is weekday, 0..6.
(while (if (memq w weekdays)
(setq day (1+ day))
- (> (setq wkday (1- wkday)) 0))
+ (>= (setq wkday (1- wkday)) 0))
(setq w (1+ w)))
(let ((hours (nth 7 math-holidays-cache)))
(if hours