在emacs电子表格中使用日期时间

时间:2014-10-08 14:44:33

标签: emacs elisp spreadsheet emacs-ses

我刚刚开始在emacs中使用ses-mode,我打算将它与时间戳一起使用,但是我没有设法以我可以使用的方式解析它们。

我在一周的三天进行测量,所以我在一次测量和另一次测量之间的距离是2或3天。我选择在emacs中使用ses-mode,因为它可以在我的所有计算机上运行,​​包括手机。

我的电子表格包含日期戳,电导率,温度和加仑数,后续几行如下所示:

2014-10-03  2.95  33.4  4031070
2014-10-06  3.07  33.5  4086930
2014-10-08  2.97  33.6  4119590

我会再添加两列,第一列是读数之间的天数差异,第二列是“每天加仑”值。

我没有设法将字符串时间戳解析为我可以进行计算的格式,保留在简单的emacs电子表格(SES)中。

我已尝试date-to-time,但它始终返回相同的值(14445 17280)

parse-time-string给了我一个9元组,我无法直接传递给format-time-string

1 个答案:

答案 0 :(得分:3)

函数encode-time有助于:

(let ((l (parse-time-string "2014-09-12")))
  (format-time-string "%d %m %Y" (encode-time 0 0 0 (nth 3 l) (nth 4 l) (nth 5 l))))

如果需要多次编码,则以下版本使用cl-flet来避免代码加倍。如果您在其他功能中也需要编码,则可以使用defun代替cl-flet

(eval-when (compile) (require 'cl)) ;; for cl-flet
(let ((A2 "2014-10-08")  ;; just for testing
      (A1 "2014-10-03")) ;; just for testing
  (cl-flet ((encode (str)
              (let ((l (parse-time-string str)))
                (encode-time 0 0 0 (nth 3 l) (nth 4 l) (nth 5 l)))))
    (let* ((t-prev (encode A1))
           (t-this (encode A2)))
      (/ (time-to-seconds (time-subtract t-this t-prev)) (* 24 60 60)))))

作为一项功能:

(eval-when (compile) (require 'cl)) ;; for cl-flet

(defun day-diff (date1 date2)
  "Calculate the difference of dates  in days between DATE1-STR and DATE2-STR."
  (interactive "sDate1:\nsDate2:")
  (cl-flet ((encode (str)
            (let ((l (parse-time-string str)))
              (encode-time 0 0 0 (nth 3 l) (nth 4 l) (nth 5 l)))))
    (setq date1 (encode date1)
      date2 (encode date2))
    (let ((ret (/ (time-to-seconds (time-subtract date1 date2)) (* 24 60 60))))
      (when (called-interactively-p 'any)
    (message "Day difference: %s" ret))
      ret)))

(put 'day-diff 'safe-function t)

使用calc的替代方案是:

(require 'calc)
(defun day-diff (date1 date2)
  "Calculate the difference of dates  in days between DATE1-STR and DATE2-STR."
  (interactive "sDate1:\nsDate2:")
  (let ((ret (string-to-number (calc-eval (format "<%s>-<%s>" date1 date2)))))
    (when (called-interactively-p 'any)
      (message "Day difference: %s" ret))
    ret))

如果省略了有用的功能,这几乎就是一个简单的单元格公式:(string-to-number (calc-eval (format "<%s>-<%s>" A1 A2)))

如果您想在电子表格中保存这些内容,可以将defun放在表格单元格A1中。一个更简单的例子:

(progn (defun day-diff (date1 date2) (string-to-number (calc-eval (format "<%s>-<%s>" date1 date2)))) (put 'day 'safe-function t) "Actual header")

为了获得更方便的编辑可能性,您可以切换到 M-x lisp-mode。 你找到了

^L
(ses-cell A1 "Actual Header" (progn (defun day-diff (date1 date2) (string-to-number (calc-eval (format "<%s>-<%s>" date1 date2)))) (put 'day 'safe-function t) "Actual header") nil nil)

你可以编辑。但是不要插入换行符! ses使用该文件中的行号识别单元格位置!


另一个不错的选择是将函数的定义放入文件局部变量列表中。 通过 M-x lisp-interaction-mode切换到lisp交互模式。 转到文件末尾。在那里你找到了这些线:

;; Local Variables:
;; mode: ses
;; End:

将您的函数定义eval添加到此列表中:

;; Local Variables:
;; mode: ses
;; eval:
;; (progn
;;   (defun day-diff (date1 date2)
;;     (string-to-number (calc-eval (format "<%s>-<%s>" date1 date2))))
;;   (put 'day-diff 'safe-function t))
;; End:

您可以添加progn而不添加评论字符;。在这种情况下甚至缩进工作。之后,您可以为comment-region致电progn

您可以保存文件并运行 M-x normal-mode。之后定义了该功能,您可以在电子表格中使用它。