extend date->seconds' and find-seconds' to work with UTC

Closes PR 6137
This commit is contained in:
Matthew Flatt 2011-01-16 17:47:11 -07:00
parent b1e13e7f3f
commit 113e49aa5b
3 changed files with 40 additions and 29 deletions

View File

@ -7,16 +7,17 @@
(provide/contract
[current-date (-> date?)]
[date->seconds (date? . -> . exact-integer?)]
[date->seconds ((date?) (any/c) . ->* . exact-integer?)]
[date->string ((date?) (any/c) . ->* . string?)]
[date-display-format (parameter/c (symbols 'american 'chinese 'german 'indian 'irish 'julian 'iso-8601 'rfc2822))]
[find-seconds ((integer-in 0 61)
(integer-in 0 59)
(integer-in 0 23)
(integer-in 1 31)
(integer-in 1 12)
exact-nonnegative-integer?
. -> .
[find-seconds (((integer-in 0 61)
(integer-in 0 59)
(integer-in 0 23)
(integer-in 1 31)
(integer-in 1 12)
exact-nonnegative-integer?)
(any/c)
. ->* .
exact-integer?)]
[date->julian/scalinger (date? . -> . exact-integer?)]
[julian/scalinger->string (exact-integer? . -> . string?)])
@ -252,16 +253,17 @@
(lambda ()
(force d))))
(define (date->seconds date)
(define (date->seconds date [local-time? #t])
(find-seconds
(date-second date)
(date-minute date)
(date-hour date)
(date-day date)
(date-month date)
(date-year date)))
(date-year date)
local-time?))
(define (find-seconds sec min hour day month year)
(define (find-seconds sec min hour day month year [local-time? #t])
(define (signal-error msg)
(error 'find-secs (string-append
msg
@ -270,7 +272,7 @@
(let loop ([below-secs (get-min-seconds)]
[secs (floor (/ (+ (get-min-seconds) (get-max-seconds)) 2))]
[above-secs (get-max-seconds)])
(let* ([date (seconds->date secs)]
(let* ([date (seconds->date secs local-time?)]
[compare
(let loop ([inputs (list year month day
hour min sec)]

View File

@ -26,7 +26,7 @@ and returns an instance of the @racket[date] structure type. If
The resulting @racket[date] reflects the time according to the local
time zone if @racket[local-time?] is @racket[#t], otherwise it
reflects a date in GMT.
reflects a date in UTC.
The value returned by @racket[current-seconds] or
@racket[file-or-directory-modify-seconds] is not portable among
@ -52,7 +52,7 @@ leap years.
The @racket[dst?] field is @racket[#t] if the date reflects a
daylight-saving adjustment. The @racket[time-zone-offset] field
reports the number of seconds east of GMT for the current time zone
reports the number of seconds east of UTC (GMT) for the current time zone
(e.g., Pacific Standard Time is @racket[-28800]), including any
daylight-saving adjustment (e.g., Pacific Daylight Time is
@racket[-25200]). When a @racket[date] record is generated by
@ -166,8 +166,11 @@ day only if @racket[time?]. See also @racket[date-display-format].}
Parameter that determines the date string format. The initial format
is @racket['american].}
@defproc[(date->seconds [date date?]) exact-integer?]{
Finds the representation of a date in platform-specific seconds. If
@defproc[(date->seconds [date date?][local-time? any/c #f]) exact-integer?]{
Finds the representation of a date in platform-specific seconds.
The @racket[time-zone-offset] field of @racket[date] is ignored;
the date is assumed to be in local time by default or in UTC
if @racket[local-time?] is @racket[#f]. If
the platform cannot represent the specified date, an error is
signaled, otherwise an integer is returned. }
@ -176,13 +179,15 @@ signaled, otherwise an integer is returned. }
[hour (integer-in 0 23)]
[day (integer-in 1 31)]
[month (integer-in 1 12)]
[year exact-nonnegative-integer?])
[year exact-nonnegative-integer?]
[local-time? any/c #t])
exact-integer?]{
Finds the representation of a date in platform-specific seconds. The
arguments correspond to the fields of the @racket[date] structure. If
the platform cannot represent the specified date, an error is
signaled, otherwise an integer is returned.}
arguments correspond to the fields of the @racket[date] structure---in
local time by default or UTC if @racket[local-time?] is
@racket[#f]. If the platform cannot represent the specified date, an
error is signaled, otherwise an integer is returned.}
@defproc[(date->julian/scalinger [date date?]) exact-integer?]{

View File

@ -6,19 +6,23 @@
(require mzlib/date)
(define (test-find s m h d mo y)
(let* ([secs (find-seconds s m h d mo y)]
[date (seconds->date secs)])
(test #t 'same
(and (= s (date-second date))
(= m (date-minute date))
(= h (date-hour date))
(= d (date-day date))
(= mo (date-month date))
(= y (date-year date))))))
(for ([local-time? (in-list '(#f #t))])
(let* ([secs (find-seconds s m h d mo y local-time?)]
[date (seconds->date secs local-time?)])
(test #t 'same
(and (= s (date-second date))
(= m (date-minute date))
(= h (date-hour date))
(= d (date-day date))
(= mo (date-month date))
(= y (date-year date)))))))
(test-find 0 0 0 1 4 1975)
(test-find 0 0 0 1 4 2005)
(test 0 find-seconds 0 0 0 1 1 1970 #f)
(test 32416215 find-seconds 15 30 4 11 1 1971 #f)
; date->string
(let* ([secs (find-seconds 1 2 3 4 5 2006)]
[d-some-tz (seconds->date secs)]