summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2019-07-08 20:38:06 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2019-07-08 20:38:06 +0200
commit53f7e58a838f766d844a37c10a69d10e758872a6 (patch)
tree85b06e66ee1a391195ac0e26d8ac6aad3cfd6b2c
parentb3cb5b76afc91ce05bdd9d389118fe47b9b9030a (diff)
downloademacs-53f7e58a838f766d844a37c10a69d10e758872a6.tar.gz
Start implementing the ISO test corpus
-rw-r--r--lisp/calendar/iso8601.el54
-rw-r--r--test/lisp/calendar/iso8601-tests.el37
2 files changed, 68 insertions, 23 deletions
diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el
index e2fddfb8cd9..67c39a0d980 100644
--- a/lisp/calendar/iso8601.el
+++ b/lisp/calendar/iso8601.el
@@ -44,15 +44,15 @@
(defconst iso8601--year-match
"\\([-+]\\)?\\([0-9][0-9][0-9][0-9]\\)")
(defconst iso8601--full-date-match
- "\\([0-9][0-9][0-9][0-9]\\)-?\\([0-9][0-9]\\)-?\\([0-9][0-9]\\)")
+ "\\([-+]\\)?\\([0-9][0-9][0-9][0-9]\\)-?\\([0-9][0-9]\\)-?\\([0-9][0-9]\\)")
(defconst iso8601--without-day-match
- "\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)")
+ "\\([-+]\\)?\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)")
(defconst iso8601--outdated-date-match
"--\\([0-9][0-9]\\)-?\\([0-9][0-9]\\)")
(defconst iso8601--week-date-match
- "\\([0-9][0-9][0-9][0-9]\\)-?W\\([0-9][0-9]\\)-?\\([0-9]\\)?")
+ "\\([-+]\\)?\\([0-9][0-9][0-9][0-9]\\)-?W\\([0-9][0-9]\\)-?\\([0-9]\\)?")
(defconst iso8601--ordinal-date-match
- "\\([0-9][0-9][0-9][0-9]\\)-?\\([0-9][0-9][0-9]\\)")
+ "\\([-+]\\)?\\([0-9][0-9][0-9][0-9]\\)-?\\([0-9][0-9][0-9]\\)")
(defconst iso8601--date-match
(iso8601--concat-regexps
(list iso8601--year-match
@@ -118,24 +118,22 @@ well as variants like \"2008W32\" (week number) and
(cond
;; Just a year: [-+]YYYY.
((iso8601--match iso8601--year-match string)
- (let ((year (string-to-number (match-string 2 string)))
- (sign (match-string 1 string)))
- (iso8601--decoded-time
- :year (if (string= sign "-")
- ;; -0001 is 2 BCE.
- (- year 1)
- year))))
+ (iso8601--decoded-time
+ :year (iso8601--adjust-year (match-string 1 string)
+ (match-string 2 string))))
;; Calendar dates: YYYY-MM-DD and variants.
((iso8601--match iso8601--full-date-match string)
(iso8601--decoded-time
- :year (match-string 1 string)
- :month (match-string 2 string)
- :day (match-string 3 string)))
+ :year (iso8601--adjust-year (match-string 1 string)
+ (match-string 2 string))
+ :month (match-string 3 string)
+ :day (match-string 4 string)))
;; Calendar date without day: YYYY-MM.
((iso8601--match iso8601--without-day-match string)
(iso8601--decoded-time
- :year (match-string 1 string)
- :month (match-string 2 string)))
+ :year (iso8601--adjust-year (match-string 1 string)
+ (match-string 2 string))
+ :month (match-string 3 string)))
;; Outdated date without year: --MM-DD
((iso8601--match iso8601--outdated-date-match string)
(iso8601--decoded-time
@@ -143,10 +141,11 @@ well as variants like \"2008W32\" (week number) and
:day (match-string 2 string)))
;; Week dates: YYYY-Www-D
((iso8601--match iso8601--week-date-match string)
- (let* ((year (string-to-number (match-string 1 string)))
- (week (string-to-number (match-string 2 string)))
- (day-of-week (and (match-string 3 string)
- (string-to-number (match-string 3 string))))
+ (let* ((year (iso8601--adjust-year (match-string 1 string)
+ (match-string 2 string)))
+ (week (string-to-number (match-string 3 string)))
+ (day-of-week (and (match-string 4 string)
+ (string-to-number (match-string 4 string))))
(jan-start (decoded-time-weekday
(decode-time
(encode-time
@@ -174,8 +173,9 @@ well as variants like \"2008W32\" (week number) and
:day (decoded-time-day month-day)))))
;; Ordinal dates: YYYY-DDD
((iso8601--match iso8601--ordinal-date-match string)
- (let* ((year (string-to-number (match-string 1 string)))
- (ordinal (string-to-number (match-string 2 string)))
+ (let* ((year (iso8601--adjust-year (match-string 1 string)
+ (match-string 2 string)))
+ (ordinal (string-to-number (match-string 3 string)))
(month-day (date-ordinal-to-time year ordinal)))
(iso8601--decoded-time :year year
:month (decoded-time-month month-day)
@@ -183,6 +183,16 @@ well as variants like \"2008W32\" (week number) and
(t
(signal 'wrong-type-argument string))))
+(defun iso8601--adjust-year (sign year)
+ (save-match-data
+ (let ((year (if (stringp year)
+ (string-to-number year)
+ year)))
+ (if (string= sign "-")
+ ;; -0001 is 2 BCE.
+ (1- (- year))
+ year))))
+
(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))
diff --git a/test/lisp/calendar/iso8601-tests.el b/test/lisp/calendar/iso8601-tests.el
index 29f599bc338..88d656290aa 100644
--- a/test/lisp/calendar/iso8601-tests.el
+++ b/test/lisp/calendar/iso8601-tests.el
@@ -26,7 +26,7 @@
(should (equal (iso8601-parse-date "1985")
'(0 0 0 1 1 1985 nil nil nil)))
(should (equal (iso8601-parse-date "-0003")
- '(0 0 0 1 1 2 nil nil nil)))
+ '(0 0 0 1 1 -4 nil nil nil)))
(should (equal (iso8601-parse-date "+1985")
'(0 0 0 1 1 1985 nil nil nil))))
@@ -107,4 +107,39 @@
(0 30 15 11 5 2008 nil nil 0)
(0 30 2 10 2 1 nil nil nil)))))
+(ert-deftest standard-test-dates ()
+ (should (equal (iso8601-parse-date "19850412")
+ '(0 0 0 12 4 1985 nil nil nil)))
+ (should (equal (iso8601-parse-date "1985-04-12")
+ '(0 0 0 12 4 1985 nil nil nil)))
+
+ (should (equal (iso8601-parse-date "1985102")
+ '(0 0 0 12 4 1985 nil nil nil)))
+ (should (equal (iso8601-parse-date "1985-102")
+ '(0 0 0 12 4 1985 nil nil nil)))
+
+ (should (equal (iso8601-parse-date "1985W155")
+ '(0 0 0 12 4 1985 nil nil nil)))
+ (should (equal (iso8601-parse-date "1985-W15-5")
+ '(0 0 0 12 4 1985 nil nil nil)))
+
+ (should (equal (iso8601-parse-date "1985W15")
+ '(0 0 0 7 4 1985 nil nil nil)))
+ (should (equal (iso8601-parse-date "1985-W15")
+ '(0 0 0 7 4 1985 nil nil nil)))
+
+ (should (equal (iso8601-parse-date "1985-04")
+ '(0 0 0 1 4 1985 nil nil nil)))
+
+ (should (equal (iso8601-parse-date "1985")
+ '(0 0 0 1 1 1985 nil nil nil)))
+
+ (should (equal (iso8601-parse-date "+1985-04-12")
+ '(0 0 0 12 4 1985 nil nil nil)))
+ (should (equal (iso8601-parse-date "+19850412")
+ '(0 0 0 12 4 1985 nil nil nil)))
+
+ )
+
+
;;; iso8601-tests.el ends here