Calc: fix formatting and parsing Unix time (bug#43759)
The number of days from epoch to Jan 1, 1970 that was used in parsing
and formatting Unix time was incorrect. The previous fix
(in e368697ce3
) was incomplete.
Reported by Vincent Belaïche.
* lisp/calc/calc-forms.el (math-unix-epoch): New constant.
(math-format-date-part, math-parse-standard-date, calcFunc-unixtime):
Use math-unix-epoch instead of a constant that is sometimes wrong.
* test/lisp/calc/calc-tests.el (calc-unix-date): New test.
This commit is contained in:
parent
6a64660318
commit
0ade20f49f
2 changed files with 49 additions and 4 deletions
|
@ -709,6 +709,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 +734,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
|
||||
|
@ -1173,7 +1178,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)
|
||||
|
@ -1434,11 +1439,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))))
|
||||
|
||||
|
|
|
@ -534,6 +534,46 @@ An existing calc stack is reused, otherwise a new one is created."
|
|||
)
|
||||
))
|
||||
|
||||
(ert-deftest calc-unix-date ()
|
||||
(let* ((d-1970-01-01 (math-parse-date "1970-01-01"))
|
||||
(d-2020-09-07 (math-parse-date "2020-09-07"))
|
||||
(d-1991-01-09-0600 (math-parse-date "1991-01-09 06:00")))
|
||||
;; calcFunc-unixtime (command "t U") converts a date value to Unix time,
|
||||
;; and a number to a date.
|
||||
(should (equal d-1970-01-01 '(date 719163)))
|
||||
(should (equal (calcFunc-unixtime d-1970-01-01 0) 0))
|
||||
(should (equal (calc-tests--calc-to-number (cadr (calcFunc-unixtime 0 0)))
|
||||
(cadr d-1970-01-01)))
|
||||
(should (equal (calcFunc-unixtime d-2020-09-07 0)
|
||||
(* (- (cadr d-2020-09-07)
|
||||
(cadr d-1970-01-01))
|
||||
86400)))
|
||||
(should (equal (calcFunc-unixtime d-1991-01-09-0600 0)
|
||||
663400800))
|
||||
(should (equal (calc-tests--calc-to-number
|
||||
(cadr (calcFunc-unixtime 663400800 0)))
|
||||
726841.25))
|
||||
|
||||
(let ((calc-date-format '(U)))
|
||||
;; Test parsing Unix time.
|
||||
(should (equal (calc-tests--calc-to-number
|
||||
(cadr (math-parse-date "0")))
|
||||
719163))
|
||||
(should (equal (calc-tests--calc-to-number
|
||||
(cadr (math-parse-date "469324800")))
|
||||
(+ 719163 (/ 469324800 86400))))
|
||||
(should (equal (calc-tests--calc-to-number
|
||||
(cadr (math-parse-date "663400800")))
|
||||
726841.25))
|
||||
|
||||
;; Test formatting Unix time.
|
||||
(should (equal (math-format-date d-1970-01-01) "0"))
|
||||
(should (equal (math-format-date d-2020-09-07)
|
||||
(number-to-string (* (- (cadr d-2020-09-07)
|
||||
(cadr d-1970-01-01))
|
||||
86400))))
|
||||
(should (equal (math-format-date d-1991-01-09-0600) "663400800")))))
|
||||
|
||||
(provide 'calc-tests)
|
||||
;;; calc-tests.el ends here
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue