-(eval-and-compile
- (eval
- '(if (not (string-match "XEmacs" emacs-version))
- (require 'parse-time)
-
- (require 'timezone)
- (defun parse-time-string (date)
- "Convert DATE into time."
- (decode-time
- (condition-case ()
- (let* ((d1 (timezone-parse-date date))
- (t1 (timezone-parse-time (aref d1 3))))
- (apply 'encode-time
- (mapcar (lambda (el)
- (and el (string-to-number el)))
- (list
- (aref t1 2) (aref t1 1) (aref t1 0)
- (aref d1 2) (aref d1 1) (aref d1 0)
- (number-to-string
- (* 60 (timezone-zone-to-minute (aref d1 4))))))))
- ;; If we get an error, then we just return a 0 time.
- (error (list 0 0))))))))
+(eval-when-compile (require 'cl))
+
+(defmacro with-decoded-time-value (varlist &rest body)
+ "Decode a time value and bind it according to VARLIST, then eval BODY.
+
+The value of the last form in BODY is returned.
+
+Each element of the list VARLIST is a list of the form
+\(HIGH-SYMBOL LOW-SYMBOL MICRO-SYMBOL [TYPE-SYMBOL] TIME-VALUE).
+The time value TIME-VALUE is decoded and the result it bound to
+the symbols HIGH-SYMBOL, LOW-SYMBOL and MICRO-SYMBOL.
+
+The optional TYPE-SYMBOL is bound to the type of the time value.
+Type 0 is the cons cell (HIGH . LOW), type 1 is the list (HIGH
+LOW), and type 3 is the list (HIGH LOW MICRO)."
+ (declare (indent 1)
+ (debug ((&rest (symbolp symbolp symbolp &or [symbolp form] form))
+ body)))
+ (if varlist
+ (let* ((elt (pop varlist))
+ (high (pop elt))
+ (low (pop elt))
+ (micro (pop elt))
+ (type (unless (eq (length elt) 1)
+ (pop elt)))
+ (time-value (car elt))
+ (gensym (make-symbol "time")))
+ `(let* ,(append `((,gensym ,time-value)
+ (,high (pop ,gensym))
+ ,low ,micro)
+ (when type `(,type)))
+ (if (consp ,gensym)
+ (progn
+ (setq ,low (pop ,gensym))
+ (if ,gensym
+ ,(append `(setq ,micro (car ,gensym))
+ (when type `(,type 2)))
+ ,(append `(setq ,micro 0)
+ (when type `(,type 1)))))
+ ,(append `(setq ,low ,gensym ,micro 0)
+ (when type `(,type 0))))
+ (with-decoded-time-value ,varlist ,@body)))
+ `(progn ,@body)))
+
+(defun encode-time-value (high low micro type)
+ "Encode HIGH, LOW, and MICRO into a time value of type TYPE.
+Type 0 is the cons cell (HIGH . LOW), type 1 is the list (HIGH LOW),
+and type 3 is the list (HIGH LOW MICRO)."
+ (cond
+ ((eq type 0) (cons high low))
+ ((eq type 1) (list high low))
+ ((eq type 2) (list high low micro))))