+(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))))