[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug?: date <-> time-monotonic roundtrip (and fixes)


A little while ago I reported a problem with the SRFI-19 reference implementation (see <http://srfi.schemers.org/srfi-19/post-mail- archive/msg00023.html).

I include below fixes for TIME-MONOTONIC->DATE, COPY-TIME and DATE- >JULIAN-DAY (as discussed by John Clements in <http:// srfi.schemers.org/srfi-19/post-mail-archive/msg00016.html>). I also include some test code.

COPY-TIME should be:

(define (copy-time time)
  (make-time (time-type time)
             (time-nanosecond time)
             (time-second time)))

The seconds and nanoseconds are the wrong way round in the RI.

In the RI's TM:CURRENT-TIME-UTC, TM:CURRENT-TIME-TAI, TM:CURRENT-TIME- MS-TIME, and TM:CURRENT-TIME-MONOTONIC, there appear to be 10000 nanoseconds in a second. Unless mzscheme's CURRENT-MILLISECONDS actually reports in units of 10^-5 seconds, I think there might be an error here.

DATE->JULIAN-DATE should I think be:

(define (date->julian-day date)
  (let ( (nanosecond (date-nanosecond date))
         (second (date-second date))
         (minute (date-minute date))
         (hour (date-hour date))
         (day (date-day date))
         (month (date-month date))
         (year (date-year date))
         (offset (date-zone-offset date)) )
    (+ (tm:encode-julian-day-number day month year)
       (- 1/2)
       (/ (+ (* hour 60 60)
             (* minute 60)
             (/ nanosecond tm:nano)
             (- offset))

As John Clements notes, what's in the RI causes a division-by-zero error whenever the time-zone offset is zero.

TIME-MONOTONIC->DATE should, I believe, be

(define (time-monotonic->date time . tz-offset)
  (let ((copy-tai (copy-time time)))
    (set-time-type! copy-tai time-tai)
(time-tai->date copy-tai (:optional tz-offset (tm:local-tz- offset)))))

...for the reasons described in the earlier message

These aren't in the form of a simple patch, I'm afraid: I'm testing this in the context of SISC's SRFI-19 port, which includes a certain amount of reordering demanded by its module system.

Can I also suggest a couple of additions to the test suite, one testing DATE->JULIAN-DAY and the other the various date->time round trips:

(define-s19-test! "Date-JD conversions"
  (lambda ()
(and (= (date->julian-day (make-date 0 0 0 12 25 2 1996 0)) ; zero TZ offset
         ;; ...and the same civil time, 6 hours further east
(= (date->julian-day (make-date 0 0 0 12 25 2 1996 (* 6 3600)))
            (- 2450139 1/4)))))

(define-s19-test! "Time to date round-trips"
  (lambda ()
    (let ((zero-diff (make-time 'time-duration 0 0)))
      (and (let ((x (current-time 'time-monotonic)))
             (time=? zero-diff
(date->time-monotonic ;round-trip monotonic- date-monotonic
                       (time-monotonic->date x)))))
           (let ((x (current-time 'time-tai)))
             (time=? zero-diff
                       (time-tai->date x)))))
           (let ((x (current-time 'time-utc)))
             (time=? zero-diff
                       (time-utc->date x)))))))))

I hope these are helpful.

Best wishes,


------------------------------------------------------------------------ ----
Norman Gray  /  http://nxg.me.uk
eurovotech.org  /  University of Leicester, UK