(use posix-time)  ;; utc-time->seconds

;; Format: 12/Feb/2006:00:50:39 -0500
;; TZ is relative to UTC and is already corrected for DST.

;; Convert apache formatted date to UTC time structure (struct tm).
;; We apparently cannot rely on tm_gmoff, the time zone offset,
;; working correctly, at least on OS X.  Rather than inserting our
;; timezone correction there, we offset the minutes.  This will cause
;; the minutes to be out of 0-60 range, but calling utc-time->seconds
;; will normalize the time.
(define (apache:date->utc-time str)
  (define (N start end) (string->number (substring str start end)))
  (define (tz-offset->minutes h m) (+ (* h 60) m))
  
  (define (month->number str)
    (alist-ref (string->symbol str)
               `((Jan . 0) (Feb . 1) (Mar . 2)
                 (Apr . 3) (May . 4) (Jun . 5)
                 (Jul . 6) (Aug . 7) (Sep . 8)
                 (Oct . 9) (Nov . 10) (Dec . 11))))
  (vector (N 18 20)                                       ; sec
          (- (N 15 17)                                    ; min adjusted for TZ
             (tz-offset->minutes (N 21 24) (N 24 26)))
          (N 12 14)                                       ; hours
          (N 0 2)                                         ; mday
          (month->number (substring str 3 6))             ; month
          (- (N 7 11) 1900)                               ; years since 1900
          0 0                                             ; wday, yday -- ignored
          #f                                              ; isdst - ignored by utc-time
          0))                                             ; tm_gmoff - unusable

;; Convert apache date to seconds since UNIX epoch.  You can retrieve
;; a string format with (time->string (seconds->local-time x)).
(define (apache:date->seconds str)
  (utc-time->seconds (apache:date->utc-time str)))

