diff options
| author | Lars Ingebrigtsen | 2019-07-31 15:17:04 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2019-07-31 21:47:29 +0200 |
| commit | 296002ba5aefa60f8a1f97c4d28808683247ce8b (patch) | |
| tree | b5f79a9da8c4e91aa65f1ab77246ae00bd10631f | |
| parent | fa648a59c9818ae284209ac7ae4f3700aebd92c9 (diff) | |
| download | emacs-296002ba5aefa60f8a1f97c4d28808683247ce8b.tar.gz emacs-296002ba5aefa60f8a1f97c4d28808683247ce8b.zip | |
Rewrite `parse-iso8601-time-string' to use `iso8601-parse'
* lisp/calendar/parse-time.el (parse-iso8601-time-string): Use
`iso8601-parse'.
(parse-time-iso8601-regexp): Remove.
| -rw-r--r-- | lisp/calendar/parse-time.el | 74 |
1 files changed, 9 insertions, 65 deletions
diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index 68d6ce05d6c..e28df97918e 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el | |||
| @@ -36,6 +36,8 @@ | |||
| 36 | ;;; Code: | 36 | ;;; Code: |
| 37 | 37 | ||
| 38 | (require 'cl-lib) | 38 | (require 'cl-lib) |
| 39 | (require 'iso8601) | ||
| 40 | (eval-when-compile (require 'subr-x)) | ||
| 39 | 41 | ||
| 40 | ;; Byte-compiler warnings | 42 | ;; Byte-compiler warnings |
| 41 | (defvar parse-time-elt) | 43 | (defvar parse-time-elt) |
| @@ -193,75 +195,17 @@ unknown DST value is returned as -1." | |||
| 193 | (setf (nth (pop slots) time) new-val)))))))) | 195 | (setf (nth (pop slots) time) new-val)))))))) |
| 194 | time)) | 196 | time)) |
| 195 | 197 | ||
| 196 | (defconst parse-time-iso8601-regexp | ||
| 197 | (let* ((dash "-?") | ||
| 198 | (colon ":?") | ||
| 199 | (4digit "\\([0-9][0-9][0-9][0-9]\\)") | ||
| 200 | (2digit "\\([0-9][0-9]\\)") | ||
| 201 | (date-fullyear 4digit) | ||
| 202 | (date-month 2digit) | ||
| 203 | (date-mday 2digit) | ||
| 204 | (time-hour 2digit) | ||
| 205 | (time-minute 2digit) | ||
| 206 | (time-second 2digit) | ||
| 207 | (time-secfrac "\\(\\.[0-9]+\\)?") | ||
| 208 | (time-numoffset (concat "\\([-+]\\)" time-hour ":?" time-minute "?")) | ||
| 209 | (partial-time (concat time-hour colon time-minute colon time-second | ||
| 210 | time-secfrac)) | ||
| 211 | (full-date (concat date-fullyear dash date-month dash date-mday))) | ||
| 212 | (list (concat "^" full-date) | ||
| 213 | (concat "T" partial-time) | ||
| 214 | (concat "\\(Z\\|" time-numoffset "\\)"))) | ||
| 215 | "List of regular expressions matching ISO 8601 dates. | ||
| 216 | 1st regular expression matches the date. | ||
| 217 | 2nd regular expression matches the time. | ||
| 218 | 3rd regular expression matches the (optional) timezone specification.") | ||
| 219 | |||
| 220 | (defun parse-iso8601-time-string (date-string) | 198 | (defun parse-iso8601-time-string (date-string) |
| 221 | "Parse an ISO 8601 time string, such as 2016-12-01T23:35:06-05:00. | 199 | "Parse an ISO 8601 time string, such as 2016-12-01T23:35:06-05:00. |
| 222 | If DATE-STRING cannot be parsed, it falls back to | 200 | If DATE-STRING cannot be parsed, it falls back to |
| 223 | `parse-time-string'." | 201 | `parse-time-string'." |
| 224 | (let* ((date-re (nth 0 parse-time-iso8601-regexp)) | 202 | (when-let ((time |
| 225 | (time-re (nth 1 parse-time-iso8601-regexp)) | 203 | (if (iso8601-valid-p date-string) |
| 226 | (tz-re (nth 2 parse-time-iso8601-regexp)) | 204 | (decoded-time-set-defaults (iso8601-parse date-string)) |
| 227 | re-start | 205 | ;; Fall back to having `parse-time-string' do fancy |
| 228 | time seconds minute hour | 206 | ;; things for us. |
| 229 | day month year day-of-week (dst -1) tz) | 207 | (parse-time-string date-string)))) |
| 230 | ;; We need to populate 'time' with | 208 | (encode-time time))) |
| 231 | ;; (SEC MIN HOUR DAY MON YEAR DOW DST TZ) | ||
| 232 | |||
| 233 | ;; Nobody else handles iso8601 correctly, let's do it ourselves. | ||
| 234 | (when (string-match date-re date-string re-start) | ||
| 235 | (setq year (string-to-number (match-string 1 date-string)) | ||
| 236 | month (string-to-number (match-string 2 date-string)) | ||
| 237 | day (string-to-number (match-string 3 date-string)) | ||
| 238 | re-start (match-end 0)) | ||
| 239 | (when (string-match time-re date-string re-start) | ||
| 240 | (setq hour (string-to-number (match-string 1 date-string)) | ||
| 241 | minute (string-to-number (match-string 2 date-string)) | ||
| 242 | seconds (string-to-number (match-string 3 date-string)) | ||
| 243 | re-start (match-end 0)) | ||
| 244 | (when (string-match tz-re date-string re-start) | ||
| 245 | (setq dst nil) | ||
| 246 | (setq tz (if (string= "Z" (match-string 1 date-string)) | ||
| 247 | 0 ;; UTC timezone indicated by Z | ||
| 248 | (let ((tz (+ | ||
| 249 | (* 3600 | ||
| 250 | (string-to-number | ||
| 251 | (match-string 3 date-string))) | ||
| 252 | (* 60 | ||
| 253 | (string-to-number | ||
| 254 | (or (match-string 4 date-string) "0")))))) | ||
| 255 | (if (string= "-" (match-string 2 date-string)) | ||
| 256 | (- tz) tz))))) | ||
| 257 | (setq time (list seconds minute hour day month year day-of-week dst tz)))) | ||
| 258 | |||
| 259 | ;; Fall back to having `parse-time-string' do fancy things for us. | ||
| 260 | (when (not time) | ||
| 261 | (setq time (parse-time-string date-string))) | ||
| 262 | |||
| 263 | (and time | ||
| 264 | (encode-time time)))) | ||
| 265 | 209 | ||
| 266 | (provide 'parse-time) | 210 | (provide 'parse-time) |
| 267 | 211 | ||