anchor.diff:                            month
                             year
                             :offset offset
  +                          :timezone timezone
                             :into into)))))
   
   (defmacro with-decoded-timestamp ((&key nsec sec minute hour day month year day-of-week daylight-p timezone offset)
  
positive.code:         (incf result (/ nsec 1000000000d0)))
        result)))
  
  (defun timestamp+ (time amount unit)
    (multiple-value-bind (nsec sec day)
        (%offset-timestamp-part time unit amount)
      (make-timestamp :nsec nsec
                      :sec sec
                      :day day)))
  
  (defun timestamp- (time amount unit)
    (multiple-value-bind (nsec sec day)
        (%offset-timestamp-part time unit (- amount))
      (make-timestamp :nsec nsec
                      :sec sec
                      :day day)))
  
  (defun timestamp-day-of-week (timestamp &key (timezone *default-timezone*) offset)
    (mod (+ 3 (nth-value 1 (%adjust-to-timezone timestamp timezone offset))) 7))
  
negative.code:                                                 7
                                                  day-of-week))
                                           position)))
                            (incf day offset)
                            (when (< day 1)
                              (let (days-in-month)
                                (decf month)
                                (when (< month 1)
                                  (setf month 12)
                                  (decf year))
                                (setf days-in-month (days-in-month month year)
                                      day (+ days-in-month day)))) ;; day here is always <= 0
                            ;; FIXME don't use encode-timestamp because it's ambiguous  
                            (encode-timestamp-into-values nsec sec minute hour day month year :timezone timezone)))))
                     ((zerop offset)
                      ;; The offset is zero, so just return the parts of the timestamp object
                      (values nsec sec day))
                     (t
                      (let ((old-utc-offset (or utc-offset
                                            (timestamp-subtimezone time timezone)))
                            new-utc-offset)
                        (tagbody
                           top
                           (ecase part
                             (:nsec
                              (multiple-value-bind (sec-offset new-nsec)
                                  (floor (+ offset nsec) 1000000000)
                                ;; the time might need to be adjusted a bit more if q != 0
                                (setf part :sec
                                      offset sec-offset 
                                      nsec new-nsec)
                                (go top)))
                             ((:sec :minute :hour)
                              (multiple-value-bind (days-offset new-sec)
                                  (floor (+ sec (* offset (ecase part
                                                            (:sec 1)
                                                            (:minute +seconds-per-minute+)
                                                            (:hour +seconds-per-hour+))))
                                         +seconds-per-day+)
                                (setf part :day
                                      offset days-offset 
                                      sec new-sec)
                                (go top)))
                             (:day
                              (incf day offset)
                              (setf new-utc-offset (or utc-offset
                                                       (timestamp-subtimezone (make-timestamp :nsec nsec :sec sec :day day)
                                                                              timezone)))
                              (when (not (= old-utc-offset
                                            new-utc-offset))
                                ;; We hit the DST boundary. We need to restart again
                                ;; with :sec, but this time we know both old and new
                                ;; UTC offset will be the same, so it's safe to do
                                (setf part :sec
                                      offset (- old-utc-offset
                                                new-utc-offset)
                                      old-utc-offset new-utc-offset)
                                (go top))
                              (return-from direct-adjust (values nsec sec day)))))))))
  
             (safe-adjust (part offset time)
               (with-decoded-timestamp (:nsec nsec :sec sec :minute minute :hour hour :day day
                                              :month month :year year :timezone timezone)
                   time
                 (multiple-value-bind (month-new year-new)
                     (%normalize-month-year-pair
  