- "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\'" date)
- ;; Styles: (6) and (7) without timezone
- (setq year 6 month 3 day 2 time 4 zone nil))
- ((string-match
- "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
- ;; Styles: (6) and (7) with timezone and buggy timezone
- (setq year 6 month 3 day 2 time 4 zone 7))
- ((string-match
- "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]*\\'" date)
- ;; Styles: (1) and (2) without timezone
- (setq year 3 month 2 day 1 time 4 zone nil))
- ((string-match
- "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
- ;; Styles: (1) and (2) with timezone and buggy timezone
- (setq year 3 month 2 day 1 time 4 zone 5))
- ((string-match
- "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([0-9]+\\)" date)
- ;; Styles: (3) without timezone
- (setq year 4 month 1 day 2 time 3 zone nil))
- ((string-match
- "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)[ \t]+\\([0-9]+\\)" date)
- ;; Styles: (3) with timezone
- (setq year 5 month 1 day 2 time 3 zone 4))
- ((string-match
- "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
- ;; Styles: (4) with timezone
- (setq year 3 month 2 day 1 time 4 zone 5))
- ((string-match
- "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\.[0-9]+" date)
- ;; Styles: (5) without timezone.
- (setq year 3 month 2 day 1 time 4 zone nil))
- ((string-match
- "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
- ;; Styles: (8) with timezone.
- (setq year 1 month 2 day 3 time 4 zone 5))
- ((string-match
- "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)" date)
- ;; Styles: (8) without timezone.
- (setq year 1 month 2 day 3 time 4 zone nil))
- )
- (if year
- (progn
- (setq year
- (substring date (match-beginning year) (match-end year)))
- ;; It is now Dec 1992. 8 years before the end of the World.
- (if (< (length year) 4)
- (setq year (concat "19" (substring year -2 nil))))
- (setq month
- (if (= (aref date (+ (match-beginning month) 2)) ?-)
- ;; Handle numeric months, spanning exactly two digits.
- (substring date
- (match-beginning month)
- (+ (match-beginning month) 2))
- (let ((string (substring date
- (match-beginning month)
- (+ (match-beginning month) 3))))
- (int-to-string
- (cdr (assoc (upcase string) timezone-months-assoc))))))
- (setq day
- (substring date (match-beginning day) (match-end day)))
- (setq time
- (substring date (match-beginning time) (match-end time)))))
- (if zone
- (setq zone
- (substring date (match-beginning zone) (match-end zone))))
+ "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)" date)
+ ;; Styles: (1) and (2) with timezone and buggy timezone
+ ;; This is most common in mail and news,
+ ;; so it is worth trying first.
+ (setq year 3 month 2 day 1 time 4 zone 5))
+ ((string-match
+ "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]*\\'" date)
+ ;; Styles: (1) and (2) without timezone
+ (setq year 3 month 2 day 1 time 4 zone nil))
+ ((string-match
+ "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\'" date)
+ ;; Styles: (6) and (7) without timezone
+ (setq year 6 month 3 day 2 time 4 zone nil))
+ ((string-match
+ "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
+ ;; Styles: (6) and (7) with timezone and buggy timezone
+ (setq year 6 month 3 day 2 time 4 zone 7))
+ ((string-match
+ "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([0-9]+\\)" date)
+ ;; Styles: (3) without timezone
+ (setq year 4 month 1 day 2 time 3 zone nil))
+ ((string-match
+ "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)[ \t]+\\([0-9]+\\)" date)
+ ;; Styles: (3) with timezone
+ (setq year 5 month 1 day 2 time 3 zone 4))
+ ((string-match
+ "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date)
+ ;; Styles: (4) with timezone
+ (setq year 3 month 2 day 1 time 4 zone 5))
+ ((string-match
+ "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\(\\.[0-9]+\\)?[ \t]+\\([-+a-zA-Z0-9]+\\)" date)
+ ;; Styles: (5) with timezone.
+ (setq year 3 month 2 day 1 time 4 zone 6))
+ ((string-match
+ "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\(\\.[0-9]+\\)?" date)
+ ;; Styles: (5) without timezone.
+ (setq year 3 month 2 day 1 time 4 zone nil))
+ ((string-match
+ "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)" date)
+ ;; Styles: (8) with timezone.
+ (setq year 1 month 2 day 3 time 4 zone 5))
+ ((string-match
+ "\\([0-9]\\{4\\}\\)-?\\([0-9]\\{0,2\\}\\)-?\\([0-9]\\{0,2\\}\\)[T \t]+\\([0-9]\\{0,2\\}:?[0-9]\\{0,2\\}:?[0-9]\\{0,2\\}\\)[ \t]*\\([-+a-zA-Z]+[0-9:]*\\)" date)
+ ;; Styles: (8) with timezone with a colon in it.
+ (setq year 1 month 2 day 3 time 4 zone 5))
+ ((string-match
+ "\\([0-9]\\{4\\}\\)-?\\([0-9]\\{0,2\\}\\)-?\\([0-9]\\{0,2\\}\\)[T \t]+\\([0-9]+:?[0-9]+:?[0-9]+\\)" date)
+ ;; Styles: (8) without timezone.
+ (setq year 1 month 2 day 3 time 4 zone nil))
+ )
+
+ (when year
+ (setq year (match-string year date))
+ ;; Guess ambiguous years. Assume years < 69 don't predate the
+ ;; Unix Epoch, so are 2000+. Three-digit years are assumed to
+ ;; be relative to 1900.
+ (when (< (length year) 4)
+ (let ((y (string-to-number year)))
+ (when (< y 69)
+ (setq y (+ y 100)))
+ (setq year (int-to-string (+ 1900 y)))))
+ (setq month
+ (if (or (= (aref date (+ (match-beginning month) 2)) ?-)
+ (let ((n (string-to-number
+ (char-to-string
+ (aref date (+ (match-beginning month) 2))))))
+ (= (aref (number-to-string n) 0)
+ (aref date (+ (match-beginning month) 2)))))
+ ;; Handle numeric months, spanning exactly two digits.
+ (substring date
+ (match-beginning month)
+ (+ (match-beginning month) 2))
+ (let* ((string (substring date
+ (match-beginning month)
+ (+ (match-beginning month) 3)))
+ (monthnum
+ (cdr (assoc (upcase string) timezone-months-assoc))))
+ (when monthnum
+ (int-to-string monthnum)))))
+ (setq day (match-string day date))
+ (setq time (match-string time date)))
+ (when zone (setq zone (match-string zone date)))