Commit 57ca5db4 authored by Lars Ingebrigtsen's avatar Lars Ingebrigtsen

Add support for times with time zones

parent a00144ab
Pipeline #2640 failed with stage
in 51 minutes and 18 seconds
......@@ -56,11 +56,11 @@
(defconst iso8601--date-match
(iso8601--concat-regexps
(list iso8601--year-match
iso8601--full-date-match
iso8601--without-day-match
iso8601--outdated-date-match
iso8601--week-date-match
iso8601--ordinal-date-match)))
iso8601--full-date-match
iso8601--without-day-match
iso8601--outdated-date-match
iso8601--week-date-match
iso8601--ordinal-date-match)))
(defconst iso8601--time-match
"\\([0-9][0-9]\\):?\\([0-9][0-9]\\)?:?\\([0-9][0-9]\\)?\\.?\\([0-9][0-9][0-9]\\)?")
......@@ -68,6 +68,10 @@
(defconst iso8601--zone-match
"\\(Z\\|\\([-+]\\)?\\([0-9][0-9]\\):?\\([0-9][0-9]\\)?\\)")
(defconst iso8601--full-time-match
(concat "\\(" (replace-regexp-in-string "(" "(?:" iso8601--time-match) "\\)"
"\\(" iso8601--zone-match "\\)?"))
(defconst iso8601--combined-match
(concat "\\(" iso8601--date-match "\\)"
"\\(?:T\\("
......@@ -195,19 +199,25 @@ well as variants like \"2008W32\" (week number) and
(defun iso8601-parse-time (string)
"Parse STRING, which should be an ISO 8601 time string, and return a time value."
(if (not (iso8601--match iso8601--time-match string))
(if (not (iso8601--match iso8601--full-time-match string))
(signal 'wrong-type-argument string)
(let ((hour (string-to-number (match-string 1 string)))
(minute (and (match-string 2 string)
(string-to-number (match-string 2 string))))
(second (and (match-string 3 string)
(string-to-number (match-string 3 string))))
;; Hm...
(_millisecond (and (match-string 4 string)
(string-to-number (match-string 4 string)))))
(iso8601--decoded-time :hour hour
:minute (or minute 0)
:second (or second 0)))))
(let ((time (match-string 1 string))
(zone (match-string 2 string)))
(if (not (iso8601--match iso8601--time-match time))
(signal 'wrong-type-argument string)
(let ((hour (string-to-number (match-string 1 time)))
(minute (and (match-string 2 time)
(string-to-number (match-string 2 time))))
(second (and (match-string 3 time)
(string-to-number (match-string 3 time))))
;; Hm...
(_millisecond (and (match-string 4 time)
(string-to-number (match-string 4 time)))))
(iso8601--decoded-time :hour hour
:minute (or minute 0)
:second (or second 0)
:zone (and zone
(iso8601-parse-zone zone))))))))
(defun iso8601-parse-zone (string)
"Parse STRING, which should be an ISO 8601 time zone.
......
......@@ -139,7 +139,7 @@
(should (equal (iso8601-parse-date "+19850412")
'(nil nil nil 12 4 1985 nil nil nil))))
(ert-deftest standard-test-time-of-day ()
(ert-deftest standard-test-time-of-day-local-time ()
(should (equal (iso8601-parse-time "152746")
'(46 27 15 nil nil nil nil nil nil)))
(should (equal (iso8601-parse-time "15:27:46")
......@@ -153,4 +153,59 @@
(should (equal (iso8601-parse-time "15")
'(0 0 15 nil nil nil nil nil nil))))
(ert-deftest standard-test-time-of-day-fractions ()
;; decoded-time doesn't support sub-second times.
;; (should (equal (iso8601-parse-time "152735,5")
;; '(46 27 15 nil nil nil nil nil nil)))
;; (should (equal (iso8601-parse-time "15:27:35,5")
;; '(46 27 15 nil nil nil nil nil nil)))
)
(ert-deftest standard-test-time-of-day-beginning-of-day ()
(should (equal (iso8601-parse-time "000000")
'(0 0 0 nil nil nil nil nil nil)))
(should (equal (iso8601-parse-time "00:00:00")
'(0 0 0 nil nil nil nil nil nil)))
(should (equal (iso8601-parse-time "0000")
'(0 0 0 nil nil nil nil nil nil)))
(should (equal (iso8601-parse-time "00:00")
'(0 0 0 nil nil nil nil nil nil))))
(ert-deftest standard-test-time-of-day-utc ()
(should (equal (iso8601-parse-time "232030Z")
'(30 20 23 nil nil nil nil nil 0)))
(should (equal (iso8601-parse-time "23:20:30Z")
'(30 20 23 nil nil nil nil nil 0)))
(should (equal (iso8601-parse-time "2320Z")
'(0 20 23 nil nil nil nil nil 0)))
(should (equal (iso8601-parse-time "23:20Z")
'(0 20 23 nil nil nil nil nil 0)))
(should (equal (iso8601-parse-time "23Z")
'(0 0 23 nil nil nil nil nil 0))))
(ert-deftest standard-test-time-of-day-zone ()
(should (equal (iso8601-parse-time "152746+0100")
'(46 27 15 nil nil nil nil nil 60)))
(should (equal (iso8601-parse-time "15:27:46+0100")
'(46 27 15 nil nil nil nil nil 60)))
(should (equal (iso8601-parse-time "152746+01")
'(46 27 15 nil nil nil nil nil 60)))
(should (equal (iso8601-parse-time "15:27:46+01")
'(46 27 15 nil nil nil nil nil 60)))
(should (equal (iso8601-parse-time "152746-0500")
'(46 27 15 nil nil nil nil nil -300)))
(should (equal (iso8601-parse-time "15:27:46-0500")
'(46 27 15 nil nil nil nil nil -300)))
(should (equal (iso8601-parse-time "152746-05")
'(46 27 15 nil nil nil nil nil -300)))
(should (equal (iso8601-parse-time "15:27:46-05")
'(46 27 15 nil nil nil nil nil -300))))
;;; iso8601-tests.el ends here
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment