branch: elpa/datetime commit b2fe88ca31272b28c6b8c95cf08ce197fafbcbb8 Author: Paul Pogonyshev <pogonys...@gmail.com> Commit: Paul Pogonyshev <pogonys...@gmail.com>
Add timezone offset to support in `datetime-matching-regexp', for all the various formats at once; test matching everywhere we test formatting. --- datetime.el | 58 +++++++++++++++++++++++++++++++++++++++++++++------------- test/base.el | 6 +++++- test/format.el | 14 ++++++++++---- test/parse.el | 3 ++- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/datetime.el b/datetime.el index f3ec46c03e..b851c36cc5 100644 --- a/datetime.el +++ b/datetime.el @@ -1614,7 +1614,16 @@ specified otherwise. (`second-fractional (apply #'concat (make-list details (rx (any "0-9"))))) (`timezone - (signal 'datetime-unsupported-timezone nil)) + (pcase details + ((or `abbreviated `full) + (signal 'datetime-unsupported-timezone nil)) + ((or `offset-localized-short `offset-localized-full + `offset-hh?mm `offset-hhmm `offset-hh:mm `offset-hhmm?ss `offset-hh:mm?:ss + `offset-hh?mm-or-z `offset-hhmm-or-z `offset-hh:mm-or-z `offset-hhmm?ss-or-z `offset-hh:mm?:ss-or-z + `offset-hhmm) + (datetime--timezone-offset-matching-regexp details)) + (_ + (error "Unexpected timezone details `%s'" details)))) (_ (error "Unexpected value %s" type))))) (push (cond ((integerp regexp) ;; REGEXP is really the maximum value of this one- or two-digit @@ -1666,19 +1675,25 @@ Options can be a list of the following keyword arguments: (datetime--format-pattern to (datetime--parse-pattern from pattern options) options)) -;; Arguments are expected to be atoms. +;; Arguments are expected to be atoms; however, PART-TYPES may also consist of full cons-cells. (defmacro datetime--pattern-includes-p (type pattern options &rest part-types) - `(let ((parts (datetime--parse-pattern ,type ,pattern ,options)) - includes) - (while parts - (let ((part (car parts))) - (if (and (consp part) ,(if (= (length part-types) 1) - `(eq (car part) ',(car part-types)) - `(memq (car part) ',part-types))) - (setq parts nil - includes t) - (setq parts (cdr parts))))) - includes)) + (declare (indent 3)) + (let ((only-atoms (not (memq nil (mapcar #'atom part-types))))) + `(let ((parts (datetime--parse-pattern ,type ,pattern ,options)) + includes) + (while parts + (let ((part (car parts))) + (if (and (consp part) ,(if only-atoms + (if (= (length part-types) 1) + `(eq (car part) ',(car part-types)) + `(memq (car part) ',part-types)) + (if (= (length part-types) 1) + `(equal part ',(car part-types)) + `(member part ',part-types)))) + (setq parts nil + includes t) + (setq parts (cdr parts))))) + includes))) (defun datetime-pattern-locale-dependent-p (type pattern &rest options) "Determine if PATTERN includes any locale-based parts. @@ -1799,6 +1814,23 @@ OPTIONS are passed to `datetime-recode-pattern'. Currently no options can affect result of this function." (datetime--pattern-includes-p type pattern options timezone)) +(defun datetime-pattern-includes-timezone-name-p (type pattern &rest options) + "Determine if PATTERN includes timezone name. + +OPTIONS are passed to `datetime-recode-pattern'. Currently no +options can affect result of this function." + (datetime--pattern-includes-p type pattern options (timezone . full) (timezone . abbreviated))) + +(defun datetime-pattern-includes-timezone-offset-p (type pattern &rest options) + "Determine if PATTERN includes timezone offset. + +OPTIONS are passed to `datetime-recode-pattern'. Currently no +options can affect result of this function." + (datetime--pattern-includes-p type pattern options + (timezone . offset-hhmm) (timezone . offset-hh?mm) (timezone . offset-hhmm?ss) (timezone . offset-hh:mm) (timezone . offset-hh:mm?:ss) + (timezone . offset-hhmm-or-z) (timezone . offset-hh?mm-or-z) (timezone . offset-hhmm?ss-or-z) (timezone . offset-hh:mm-or-z) (timezone . offset-hh:mm?:ss-or-z) + (timezone . offset-localized-short) (timezone . offset-localized-full))) + (defsubst datetime--do-get-locale-pattern (patterns variant) (or (plist-get patterns variant) diff --git a/test/base.el b/test/base.el index 8be2f1d098..b597eca5f2 100644 --- a/test/base.el +++ b/test/base.el @@ -47,12 +47,16 @@ (defvar datetime--test-formatter nil) (defvar datetime--test-parser nil) +(defvar datetime--test-matcher nil) (defmacro datetime--test-set-up-formatter (timezone locale pattern &rest body) (declare (debug (form form form body)) (indent 3)) `(datetime--test-set-up ,timezone ,locale ,pattern - (let ((datetime--test-formatter (datetime-float-formatter 'java datetime--test-pattern :timezone datetime--test-timezone :locale datetime--test-locale))) + (let ((datetime--test-formatter (datetime-float-formatter 'java datetime--test-pattern :timezone datetime--test-timezone :locale datetime--test-locale)) + ;; Currently, `datetime-matching-regexp' doesn't support timezone names. + (datetime--test-matcher (unless (datetime-pattern-includes-timezone-name-p 'java datetime--test-pattern) + (datetime-matching-regexp 'java datetime--test-pattern :timezone datetime--test-timezone :locale datetime--test-locale)))) ,@body))) (defmacro datetime--test-set-up-parser (timezone locale pattern &rest body) diff --git a/test/format.el b/test/format.el index e9e479967f..3607e86e3c 100644 --- a/test/format.el +++ b/test/format.el @@ -22,12 +22,18 @@ (defun datetime--test-formatter (times) (unless (listp times) (setq times (list times))) - (let ((formatted (datetime--test 'format times))) + (let ((all-formatted (datetime--test 'format times))) (while times - (let ((time (pop times)) - (expected (pop formatted))) + (let* ((time (pop times)) + (expected (pop all-formatted)) + (formatted (funcall datetime--test-formatter time))) (eval `(should (progn ',datetime--test-timezone ',datetime--test-locale ,datetime--test-pattern ,time - (string= ,(funcall datetime--test-formatter time) ,expected)))))))) + (string= ,formatted ,expected))) + t) + (when datetime--test-matcher + (eval `(should (progn ',datetime--test-timezone ',datetime--test-locale ,datetime--test-pattern ,time + (string-match-p ,datetime--test-matcher ,formatted))) + t)))))) (defun datetime--test-formatter-around-transition (time) (datetime--test-formatter (list time diff --git a/test/parse.el b/test/parse.el index d944a1ebea..86522af344 100644 --- a/test/parse.el +++ b/test/parse.el @@ -49,7 +49,8 @@ (let ((as-string (pop as-strings)) (time (pop parsed))) (eval `(should (progn ',datetime--test-timezone ',datetime--test-locale ,datetime--test-pattern ,as-string - (datetime--~= ,(funcall datetime--test-parser as-string) ,time nil ,as-string)))))))) + (datetime--~= ,(funcall datetime--test-parser as-string) ,time nil ,as-string))) + t))))) (defun datetime--test-parser-around-transition (time) (datetime--test-parser (datetime--test 'format (list time