[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Shorter and more flexible implementation for parse-time.el

From: Guu, Jin-Cheng
Subject: Shorter and more flexible implementation for parse-time.el
Date: Fri, 23 Jul 2021 12:03:33 -0500


(This is my first post. Please correct me if I missed anything. =) )

Currently, the built-in time parsing functions only allow us to parse timestrings with respect to some given formats (ISO-8601, RFC-822) [1]. I have a parsing function that allows users to parse with customized formats which are easy to write. The end result is:

``` emacs-lisp
(my/parse-time "20200718-201504"
               '((:year 4) (:month 2) (:day 2) "-"
                 (:hour 2) (:minute 2) (:second 2)))
;; => ((:second . 4) (:minute . 15) (:hour . 20)
;;     (:day . 18) (:month . 7) (:year . 2020))

One can even parse org timestamps easily with the format 

``` emacs-lisp
'("[" (:year 4) "-" (:month 2) "-" (:day 2) "]")

The code is ~25 lines long, which is easily extendable (see below). I wonder if there's any interest to add this into emacs. I can write tests and benchmarks to make sure that it doesn't change the user space.

``` emacs-lisp
;;; Actual code

(defun my/parse-time (str format)
  "Parse time string with customized format, and return an alist.
A format is a list of directives. A directive is either a string
or a list (A B), where A is a keyword, and B is an integer."
  (flet ((parse-step
          (directive str)
          (if (atom directive)
              (if (string-match (format "^%s" directive) str)
                  (list (substring str (length directive)))
                (error "Parsing failure~ directive: %s; str: %s." directive str))
            (let* ((key (car directive))
                   (int (car (cdr directive)))
                   (to-parse (substring str 0 int))
                   ;; TODO For natural lang, replace
                   ;; parse-integer by any customized
                   ;; transformers.
                   (value (cl-parse-integer to-parse)))
              (list (substring str int) key value)))))
    (let (result)
      (while (not (equal str ""))
        (let* ((return (parse-step (pop format) str))
               (new-str (car return))
               (key (car (cdr return)))
               (value (car (cddr return))))
          (setf str new-str)
          (when key (setf (alist-get key result) value))))

[1] https://github.com/emacs-mirror/emacs/blob/master/lisp/calendar/parse-time.el

reply via email to

[Prev in Thread] Current Thread [Next in Thread]