Elisp: Parse Date Time
Problem
Write a elisp function. The function will take a string argument that's any of common date time format, example
2011-09-02T05:29:26-07:00
(ISO 8601)2011-09-02
(ISO 8601)Fri, 2 Sep 2011 11:14:11 +0200
(unixy)09/02/2011
(USA)Sep 2, 2011
2 Sep, 2011
2 September, 2011
and output a canonical form 2011-09-02T11:14:11+0200
.
Solution
Two builtin lib to parse datetime:
parse-time-string
, fromparse-time.el
.(require 'parse-time)
.iso8601-parse
, fromiso8601.el
.(require 'iso8601)
. (new in emacs 27)
(parse-time-string STRING)
return a list like this:
(SEC MIN HOUR DAY MON YEAR DOW DST TZ)
- SEC is an integer or Lisp timestamp representing a nonnegative value less than 60 (or less than 61 if the operating system supports leap seconds).
- MIN is an integer between 0 and 59.
- HOUR is an integer between 0 and 23.
- DAY is an integer between 1 and 31.
- MONTH is an integer between 1 and 12.
- YEAR is the year number, an integer; 0 represents 1 BC.
- DOW is the day of week, an integer between 0 and 6, where 0 is Sunday.
- DST is t if daylight saving time is in effect, nil if it is not in effect, and -1 if daylight saving information is not available.
- TZ is an integer indicating the UTC offset in seconds, i.e., the number of seconds east of Greenwich.
any values that are unknown are returned as nil. in emacs 27, unknown DST value is returned as -1.
(iso8601-parse STRING &optional FORM)
return the same format.
iso8601-parse
is designed for parsing ISO 8601 time formats.
Supported Formats of parse-time-string
;; testing what time formats parse-time-string supports ;; As of GNU Emacs 27.1 of 2020-08-11 (require 'parse-time) ;; parse-time-string returns ;; (SEC MIN HOUR DAY MON YEAR DOW DST TZ) ;; if a element is nil or -1, it means unknown (parse-time-string "Date: Mon, 01 Aug 2011 12:24:51 -0400") ;; (51 24 12 1 8 2011 1 -1 -14400) ;; yes (parse-time-string "Local: Mon, Aug 1 2011 9:24 am") ;; (0 24 9 1 8 2011 1 -1 nil) ;; yes (parse-time-string "2007, August 1") ;; (nil nil nil 1 8 2007 nil -1 nil) ;; yes (parse-time-string "August 1, 2007") ;; (nil nil nil 1 8 2007 nil -1 nil) ;; yes (parse-time-string "august 1, 2007") ;; (nil nil nil 1 8 2007 nil -1 nil) ;; yes (parse-time-string "August 1st, 2007") ;; (nil nil nil nil 8 2007 nil -1 nil) ;; no. The date is nil (parse-time-string "aug 1, 2007") (nil nil nil 1 8 2007 nil -1 nil) ;; yes (parse-time-string "1 aug, 2007") ;; (nil nil nil 1 8 2007 nil -1 nil) ;; yes (parse-time-string "8/1/2007") ;; (nil nil nil 8 nil 2001 nil -1 nil) ;; no. Takes the 8 as date, 1 as nil (parse-time-string "08/01/2007") ;; (nil nil nil 8 nil 2001 nil -1 nil) ;; no. Takes the 8 as date, 1 as nil (parse-time-string "8,1,2007") (nil nil nil 8 nil 2001 nil -1 nil) ;; no (parse-time-string "2007-08-01") ;; (nil nil nil 1 8 2007 nil -1 nil) ;; yes (parse-time-string "2007") ;; (nil nil nil nil nil 2007 nil -1 nil) ;; yes (parse-time-string "2007-08") ;; (nil nil nil nil nil nil nil -1 nil) ;; no (parse-time-string "2011-08-01T11:55:37-07:00") ;; (nil nil nil nil nil nil nil -1 nil) ;; no