summaryrefslogtreecommitdiff
path: root/lisp/calc/calc-forms.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/calc/calc-forms.el')
-rw-r--r--lisp/calc/calc-forms.el82
1 files changed, 46 insertions, 36 deletions
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index 5a8f0a38d24..465d4520b05 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -1,4 +1,4 @@
-;;; calc-forms.el --- data format conversion functions for Calc
+;;; calc-forms.el --- data format conversion functions for Calc -*- lexical-binding:t -*-
;; Copyright (C) 1990-1993, 2001-2020 Free Software Foundation, Inc.
@@ -678,10 +678,11 @@ in the Gregorian calendar."
(defvar math-fd-isoweek)
(defvar math-fd-isoweekday)
-(defun math-format-date (math-fd-date)
- (if (eq (car-safe math-fd-date) 'date)
- (setq math-fd-date (nth 1 math-fd-date)))
- (let ((entry (list math-fd-date calc-internal-prec calc-date-format)))
+(defun math-format-date (fd-date)
+ (let* ((math-fd-date (if (eq (car-safe fd-date) 'date)
+ (nth 1 fd-date)
+ fd-date))
+ (entry (list math-fd-date calc-internal-prec calc-date-format)))
(or (cdr (assoc entry math-format-date-cache))
(let* ((math-fd-dt nil)
(math-fd-iso-dt nil)
@@ -709,6 +710,10 @@ as measured in the number of days before December 31, 1 BC (Gregorian).")
"The beginning of the Julian date calendar,
as measured in the integer number of days before December 31, 1 BC (Gregorian).")
+(defconst math-unix-epoch 719163
+ "The beginning of Unix time: days from December 31, 1 BC (Gregorian)
+to Jan 1, 1970 AD.")
+
(defun math-format-date-part (x)
(cond ((stringp x)
x)
@@ -730,7 +735,8 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
(math-floor math-fd-date)
math-julian-date-beginning-int)))
((eq x 'U)
- (math-format-number (nth 1 (math-date-parts math-fd-date 719164))))
+ (math-format-number (nth 1 (math-date-parts math-fd-date
+ math-unix-epoch))))
((memq x '(IYYY Iww w))
(progn
(or math-fd-iso-dt
@@ -909,15 +915,16 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
;; which is called by math-parse-date and math-parse-standard-date.
(defvar math-pd-str)
-(defun math-parse-date (math-pd-str)
+(defun math-parse-date (pd-str)
(catch 'syntax
- (or (math-parse-standard-date math-pd-str t)
- (math-parse-standard-date math-pd-str nil)
- (and (string-match "W[0-9][0-9]" math-pd-str)
- (math-parse-iso-date math-pd-str))
- (and (string-match "\\`[^-+/0-9a-zA-Z]*\\([-+]?[0-9]+\\.?[0-9]*\\([eE][-+]?[0-9]+\\)?\\)[^-+/0-9a-zA-Z]*\\'" math-pd-str)
- (list 'date (math-read-number (math-match-substring math-pd-str 1))))
+ (or (math-parse-standard-date pd-str t)
+ (math-parse-standard-date pd-str nil)
+ (and (string-match "W[0-9][0-9]" pd-str)
+ (math-parse-iso-date pd-str))
+ (and (string-match "\\`[^-+/0-9a-zA-Z]*\\([-+]?[0-9]+\\.?[0-9]*\\([eE][-+]?[0-9]+\\)?\\)[^-+/0-9a-zA-Z]*\\'" pd-str)
+ (list 'date (math-read-number (math-match-substring pd-str 1))))
(let ((case-fold-search t)
+ (math-pd-str pd-str)
(year nil) (month nil) (day nil) (weekday nil)
(hour nil) (minute nil) (second nil) (bc-flag nil)
(a nil) (b nil) (c nil) (bigyear nil) temp)
@@ -1123,8 +1130,9 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
(substring math-pd-str (match-end 0))))
n))))
-(defun math-parse-standard-date (math-pd-str with-time)
- (let ((case-fold-search t)
+(defun math-parse-standard-date (pd-str with-time)
+ (let ((math-pd-str pd-str)
+ (case-fold-search t)
(okay t) num
(fmt calc-date-format) this next (gnext nil)
(isoyear nil) (isoweek nil) (isoweekday nil)
@@ -1173,7 +1181,7 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
(setq num (math-match-substring math-pd-str 0)
math-pd-str (substring math-pd-str (match-end 0))
num (math-date-to-dt
- (math-add 719164
+ (math-add math-unix-epoch
(math-div (math-read-number num)
'(float 864 2))))
hour (nth 3 num)
@@ -1301,9 +1309,10 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
(setq day (math-add day (1- yearday))))
day))))))
-(defun math-parse-iso-date (math-pd-str)
- "Parse MATH-PD-STR as an ISO week date, or return nil."
- (let ((case-fold-search t)
+(defun math-parse-iso-date (pd-str)
+ "Parse PD-STR as an ISO week date, or return nil."
+ (let ((math-pd-str pd-str)
+ (case-fold-search t)
(isoyear nil) (isoweek nil) (isoweekday nil)
(hour nil) (minute nil) (second nil))
;; Extract the time, if any.
@@ -1434,11 +1443,11 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
(defun calcFunc-unixtime (date &optional zone)
(if (math-realp date)
(progn
- (setq date (math-add 719163 (math-div date '(float 864 2))))
+ (setq date (math-add math-unix-epoch (math-div date '(float 864 2))))
(list 'date (math-sub date (math-div (calcFunc-tzone zone date)
'(float 864 2)))))
(if (eq (car date) 'date)
- (math-add (nth 1 (math-date-parts (nth 1 date) 719163))
+ (math-add (nth 1 (math-date-parts (nth 1 date) math-unix-epoch))
(calcFunc-tzone zone date))
(math-reject-arg date 'datep))))
@@ -1608,7 +1617,7 @@ and ends on the first Sunday of November at 2 a.m."
(math-std-daylight-savings-old date dt zone bump)
(math-std-daylight-savings-new date dt zone bump)))
-(defun math-std-daylight-savings-new (date dt zone bump)
+(defun math-std-daylight-savings-new (date dt _zone bump)
"Standard North American daylight saving algorithm as of 2007.
This implements the rules for the U.S. and Canada.
Daylight saving begins on the second Sunday of March at 2 a.m.,
@@ -1629,7 +1638,7 @@ and ends on the first Sunday of November at 2 a.m."
(t 0))))
(t 0)))
-(defun math-std-daylight-savings-old (date dt zone bump)
+(defun math-std-daylight-savings-old (date dt _zone bump)
"Standard North American daylight saving algorithm before 2007.
This implements the rules for the U.S. and Canada.
Daylight saving begins on the first Sunday of April at 2 a.m.,
@@ -1652,7 +1661,7 @@ and ends on the last Sunday of October at 2 a.m."
;;; Compute the day (1-31) of the WDAY (0-6) on or preceding the given
;;; day of the given month.
-(defun math-prev-weekday-in-month (date dt day wday)
+(defun math-prev-weekday-in-month (date dt day _wday)
(or day (setq day (nth 2 dt)))
(if (> day (math-days-in-month (car dt) (nth 1 dt)))
(setq day (math-days-in-month (car dt) (nth 1 dt))))
@@ -1870,8 +1879,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 +1914,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
@@ -2030,18 +2040,18 @@ and ends on the last Sunday of October at 2 a.m."
nil)))
(or done (setq math-holidays-cache-tag t))))))
-(defun math-setup-year-holidays (math-sh-year)
- (let ((exprs (nth 2 math-holidays-cache)))
- (while exprs
+(defun math-setup-year-holidays (sh-year)
+ (let ((math-sh-year sh-year))
+ (dolist (expr (nth 2 math-holidays-cache))
+ (defvar var-y) (defvar var-m)
(let* ((var-y math-sh-year)
(var-m nil)
- (expr (math-evaluate-expr (car exprs))))
+ (expr (math-evaluate-expr expr)))
(if (math-expr-contains expr '(var m var-m))
(let ((var-m 0))
(while (<= (setq var-m (1+ var-m)) 12)
(math-setup-add-holidays (math-evaluate-expr expr))))
- (math-setup-add-holidays expr)))
- (setq exprs (cdr exprs)))))
+ (math-setup-add-holidays expr))))))
(defun math-setup-add-holidays (days) ; uses "math-sh-year"
(cond ((eq (car-safe days) 'vec)