Re: Bug?: date <-> time-monotonic roundtrip (and fixes) Norman Gray 06 Aug 2006 18:53 UTC

Greetings.

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)
              second
              (/ nanosecond tm:nano)
              (- offset))
           tm:sid))))

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
             2450139)
          ;; ...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
                      (time-difference
                       x
                       (date->time-monotonic ;round-trip monotonic-
date-monotonic
                        (time-monotonic->date x)))))
            (let ((x (current-time 'time-tai)))
              (time=? zero-diff
                      (time-difference
                       x
                       (date->time-tai
                        (time-tai->date x)))))
            (let ((x (current-time 'time-utc)))
              (time=? zero-diff
                      (time-difference
                       x
                       (date->time-utc
                        (time-utc->date x)))))))))

I hope these are helpful.

Best wishes,

Norman

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