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