Function: iso8601-parse-date

iso8601-parse-date is a byte-compiled function defined in iso8601.el.gz.

Signature

(iso8601-parse-date STRING)

Documentation

Parse STRING (in ISO 8601 format) and return a decode-time value.

Probably introduced at or before Emacs version 27.1.

Source Code

;; Defined in /usr/src/emacs/lisp/calendar/iso8601.el.gz
(defun iso8601-parse-date (string)
  "Parse STRING (in ISO 8601 format) and return a `decode-time' value."
  (cond
   ;; Just a year: [+-]YYYY.
   ((iso8601--match iso8601--year-match string)
    (iso8601--decoded-time
     :year (string-to-number string)))
   ;; Calendar dates: YYYY-MM-DD and variants.
   ((iso8601--match iso8601--full-date-match string)
    (iso8601--decoded-time
     :year (string-to-number (match-string 1 string))
     :month (match-string 2 string)
     :day (match-string 3 string)))
   ;; Calendar date without day: YYYY-MM.
   ((iso8601--match iso8601--without-day-match string)
    (iso8601--decoded-time
     :year (string-to-number string)
     :month (match-string 2 string)))
   ;; Outdated date without year: --MM-DD
   ((iso8601--match iso8601--outdated-date-match string)
    (iso8601--decoded-time
     :month (match-string 1 string)
     :day (match-string 2 string)))
   ;; Week dates: YYYY-Www-D
   ((iso8601--match iso8601--week-date-match string)
    (let* ((year (string-to-number string))
           (week (string-to-number (match-string 2 string)))
           (day-of-week (and (match-string 3 string)
                             (string-to-number (match-string 3 string))))
           (jan-start (decoded-time-weekday
                       (decode-time
                        (iso8601--encode-time
                         (iso8601--decoded-time :year year
                                                :month 1
                                                :day 4)))))
           (correction (+ (if (zerop jan-start) 7 jan-start)
                          3))
           (ordinal (+ (* week 7) (or day-of-week 0) (- correction))))
      (cond
       ;; Monday 29 December 2008 is written "2009-W01-1".
       ((< ordinal 1)
        (setq year (1- year)
              ordinal (+ ordinal (if (date-leap-year-p year)
                                     366 365))))
       ;; Sunday 3 January 2010 is written "2009-W53-7".
       ((> ordinal (if (date-leap-year-p year)
                       366 365))
        (setq ordinal (- ordinal (if (date-leap-year-p year)
                                     366 365))
              year (1+ year))))
      (let ((month-day (date-ordinal-to-time year ordinal)))
        (iso8601--decoded-time :year year
                               :month (decoded-time-month month-day)
                               :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)))
           (month-day (date-ordinal-to-time year ordinal)))
      (iso8601--decoded-time :year year
                             :month (decoded-time-month month-day)
                             :day (decoded-time-day month-day))))
   ;; Obsolete format with implied year: --MM
   ((iso8601--match "--\\([0-9][0-9]\\)" string)
    (iso8601--decoded-time :month (string-to-number (match-string 1 string))))
   ;; Obsolete format with implied year and month: ---DD
   ((iso8601--match "---\\([0-9][0-9]\\)" string)
    (iso8601--decoded-time :day (string-to-number (match-string 1 string))))
   (t
    (signal 'wrong-type-argument string))))