#!r6rs (library (rsc3 ntp ntp) (export ntp->utc. utc->ntp utc->ntpr ntpr->ntp) (import (rnrs) (only (rsc3 math exact) round-exact)) ;; NTP is the Network Time Protocol. NTP time is represented by a 64 ;; bit fixed point number. The first 32 bits specify the number of ;; seconds since midnight on January 1, 1900, and the last 32 bits ;; specify fractional parts of a second to a precision of about 200 ;; picoseconds. This is the representation used by Internet NTP ;; timestamps. ;; The number of seconds from the start of 1900 to the start of 1970. ;; NTP is measured from the former, UTC from the latter. There are 17 ;; leap years in this period. ;; 2^32 = 4294967296 (define seconds-from-1900-to-1970 (+ (* 70 365 24 60 60) (* 17 24 60 60))) (define (ntpr->ntp i) (round-exact (* i 4294967296))) (define (ntp-to-seconds i) (/ i 4294967296)) (define (ntp-to-seconds. i) (/ i 4294967296.0)) (define (nanoseconds-to-ntp i) (round-exact (* i (/ 4294967296 (expt 10 9))))) (define (ntp-to-nanoseconds i) (* i (/ (expt 10 9) 4294967296))) ;; Convert between time intervals in seconds and NTP intervals. (define (time-interval->ntp-interval interval) (ntpr->ntp interval)) (define (ntp-interval->time-interval ntp-interval) (ntp-to-seconds ntp-interval)) (define (ntp-interval->time-interval. ntp-interval) (ntp-to-seconds. ntp-interval)) ;; Evaluate to an representing the NTP time of the UTC time of ;; the number `n'. (define (utc->ntpr n) (+ n seconds-from-1900-to-1970)) ;; Evaluate to an representing the NTP time of the UTC time ;; of the number `n'. (define (utc->ntp n) (ntpr->ntp (+ n seconds-from-1900-to-1970))) ;; Evaluate to a number representing the UTC time of the ;; NTP time `ntp'. (define (ntp->utc ntp) (- (ntp-to-seconds ntp) seconds-from-1900-to-1970)) (define (ntp->utc. ntp) (- (ntp-to-seconds. ntp) seconds-from-1900-to-1970)) )