From ff8a062bfef1b3cbf7842b23b5421c53754e50b0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 23 Jun 2012 05:47:00 +0800 Subject: [PATCH] guarantee `current-seconds', etc. from 1/1/1970 UTC For all currently supported platforms, the result was already portable, despite the documentation's hedging. Also fixed up the documentation in other ways, such as the fact that `seconds->date' returns a `date*'. --- .../scribblings/reference/filesystem.scrbl | 11 +-- collects/scribblings/reference/time.scrbl | 72 ++++++++----------- doc/release-notes/racket/HISTORY.txt | 2 + src/racket/src/fun.c | 1 + 4 files changed, 40 insertions(+), 46 deletions(-) diff --git a/collects/scribblings/reference/filesystem.scrbl b/collects/scribblings/reference/filesystem.scrbl index db1da97af0..adcfd15123 100644 --- a/collects/scribblings/reference/filesystem.scrbl +++ b/collects/scribblings/reference/filesystem.scrbl @@ -281,12 +281,13 @@ existing @racket[new].} [fail-thunk (-> any) (lambda () (raise (make-exn:fail:filesystem ....)))]) any]{ -Returns the file or directory's last modification date as -platform-specific seconds (see also @secref["time"]) when -@racket[secs-n] is not provided or is @racket[#f]. (For FAT -filesystems on Windows, directories do not have modification +Returns the file or directory's last modification date in seconds +since midnight UTC, January 1, 1970 (see also @secref["time"]) when +@racket[secs-n] is not provided or is @racket[#f]. + +For FAT filesystems on Windows, directories do not have modification dates. Therefore, the creation date is returned for a directory, but -the modification date is returned for a file.) +the modification date is returned for a file. If @racket[secs-n] is provided and not @racket[#f], the access and modification times of @racket[path] are set to the given time. diff --git a/collects/scribblings/reference/time.scrbl b/collects/scribblings/reference/time.scrbl index 67d5f7e2ad..d06f7c8e49 100644 --- a/collects/scribblings/reference/time.scrbl +++ b/collects/scribblings/reference/time.scrbl @@ -5,33 +5,38 @@ @defproc[(current-seconds) exact-integer?]{ -Returns the current time in seconds. This time is always an exact -integer based on a platform-specific starting date (with a -platform-specific minimum and maximum value). +Returns the current time in seconds since midnight UTC, January 1, +1970.} + + +@defproc[(current-inexact-milliseconds) real?]{ + +Returns the current time in milliseconds since midnight UTC, January +1, 1970. The result may contain fractions of a millisecond. + +@examples[(eval:alts +(current-inexact-milliseconds) +1289513737015.418 +)] + +In this example, @racket[1289513737015] is in milliseconds and @racket[418] +is in microseconds.} -The value of @racket[(current-seconds)] increases as time passes -(increasing by 1 for each second that passes). The current time in -seconds can be compared with a time returned by -@racket[file-or-directory-modify-seconds].} @defproc[(seconds->date [secs-n real?] [local-time? any/c #t]) - date?]{ + date*?]{ Takes @racket[secs-n], a platform-specific time in seconds returned by -@racket[current-seconds], @racket[current-inexact-milliseconds], -or @racket[file-or-directory-modify-seconds], -and returns an instance of the @racket[date*] structure type. If -@racket[secs-n] is too small or large, the @exnraise[exn:fail]. +@racket[current-seconds], @racket[file-or-directory-modify-seconds], +or 1/1000th of @racket[current-inexact-milliseconds], and returns an +instance of the @racket[date*] structure type. Note that +@racket[secs-n] can include fractions of a second. If @racket[secs-n] +is too small or large, the @exnraise[exn:fail]. -The resulting @racket[date] reflects the time according to the local +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 UTC. - -The value returned by @racket[current-seconds] or -@racket[file-or-directory-modify-seconds] is not portable among -platforms. Convert a time in seconds using @racket[seconds->date] when -portability is needed.} +reflects a date in UTC.} @defstruct[date ([second (integer-in 0 61)] [minute (integer-in 0 59)] @@ -74,8 +79,8 @@ See also the @racketmodname[racket/date] library.} @defstruct[(date* date) ([nanosecond (integer-in 0 999999999)] [time-zone-name (and/c string? immutable?)])]{ -Extends @racket[date] with a time zone name, such as @racket["MDT"], -@racket["Mountain Daylight Time"], or @racket["UTC"]. +Extends @racket[date] with nanoseconds and a time zone name, such as +@racket["MDT"], @racket["Mountain Daylight Time"], or @racket["UTC"]. When a @racket[date*] record is generated by @racket[seconds->date] with @racket[#f] as the second argument, then the @@ -87,25 +92,10 @@ The @racket[date*] constructor accepts a mutable string for @defproc[(current-milliseconds) exact-integer?]{ -Returns the current ``time'' in @tech{fixnum} milliseconds (possibly -negative). This time is based on a platform-specific starting date or -on the machine's start-up time. Since the result is a @tech{fixnum}, -the value increases only over a limited (though reasonably long) -time.} - - -@defproc[(current-inexact-milliseconds) real?]{ - -Returns the current time in milliseconds since midnight UTC, January -1, 1970. The result may contain fractions of a millisecond. - -@examples[(eval:alts -(current-inexact-milliseconds) -1289513737015.418 -)] - -In this example @racket[1289513737015] is in milliseconds and @racket[418] -is in microseconds.} +Like @racket[current-inexact-milliseconds], but coerced to a +@tech{fixnum} (possibly negative). Since the result is a +@tech{fixnum}, the value increases only over a limited (though +reasonably long) time on a 32-bit platform.} @defproc[(current-process-milliseconds [thread (or/c thread? #f)]) @@ -119,7 +109,7 @@ is for all Racket threads, otherwise the result is specific to the time while @racket[thread] ran. The precision of the result is platform-specific, and since the result is a @tech{fixnum}, the value increases only over a -limited (though reasonably long) time.} +limited (though reasonably long) time on a 32-bit platform.} @defproc[(current-gc-milliseconds) exact-integer?]{ diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index fcb7cd12d8..a72f95b390 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -5,6 +5,8 @@ racket/control: added call/prompt, call/comp, abort/cc and racket/future: handling of internal stack overflow without necessarily blocking on process 0; added 'overflow and 'start-overflow-work log events +racket/base: guarantee portable results for current-seconds + and file-or-directory-modify-seconds Version 5.3.0.10 racket/base: add progress-evt?, thread-cell-values?, prefab-key?, diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index bc2886e7aa..aa3e484ae1 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -8542,6 +8542,7 @@ intptr_t scheme_get_thread_milliseconds(Scheme_Object *thrd) intptr_t scheme_get_seconds(void) { #ifdef USE_MACTIME + /* This is wrong, since it's not since January 1, 1970 */ unsigned long secs; GetDateTime(&secs); return secs;