This SRFI is currently in final status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-174@nospamsrfi.schemers.org
. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
This SRFI defines the trivial type timespec, which is used
to represent the struct timespec
defined by the
POSIX <time.h>
header.
The reason for putting this very simple and straightforward type into a SRFI (and library) of its own is that timespecs are part of the interface for more than one SRFI. If they are defined in just one SRFI and imported by the rest, that produces an otherwise useless and unnecessary dependency on the SRFI containing the definition. This arises particularly in R6RS and R7RS because record types are generative (distinct definitions lead to distinct record types) and because most implementations report a warning or even an error if the same identifier is imported from more than one library, unless they have both imported it in turn from the same original library.
Timespec is an immutable type that holds two exact integer values:
The seconds component — If non-negative, the number of whole seconds since a particular epoch. If negative, the number of whole seconds to go back in time from the epoch. Normally excludes leap seconds (i.e. a leap second that occurs between the epoch and seconds does not increment or decrement seconds). The minimum range of values is 2-39 (inclusive) to 239 (exclusive), allowing a range of at least 15,000 years before and after the epoch.
The nanoseconds component — The partial second added to seconds. Always non-negative and less than 109. If seconds is non-negative, this is the number of additional nanoseconds to go toward the future after seconds. If seconds is negative, this is the number of additional nanoseconds to go further back in time before seconds.
It is recommended, but not absolutely required, that timespecs be a disjoint and immutable type. For efficiency's sake they may be represented otherwise in particular implementations. If they are not disjoint, the exact representation (such as a SRFI 19 time object or a pair) must be documented by the implementation.
If timespecs are represented as SRFI 19 time objects,
the timespec
constructor must set the
SRFI 19 time type to TIME_UTC
.
It is an error to mutate a time object (or pair, or other type)
that is serving as a timespec,
and if this is done, code relying on the immutability of timespecs will break.
Note that IEEE 64-bit floats are not a sufficient representation for timespecs because their nanosecond-precision range is confined to a period of 208 days centered on the epoch.
In no case can this SRFI guarantee anything about the accuracy of timespecs, or the precision of any timespec sources. Since it is difficult to usefully determine and communicate timestamp precision and accuracy in most applications, the timespec type does not contain any standard field to hold such information.
An implementation of this SRFI must document:
(timespec
seconds nanoseconds)
Returns a timespec with the given seconds and nanoseconds components.
(timespec?
obj)
Returns #f
if obj is definitely not a timespec,
and #t
if it is most probably one.
If timespecs are a disjoint type, this procedure simply tests whether obj belongs to that type. If not, then each component is checked to see if it is an exact integer, and in the case of the nanoseconds component, whether it is a non-negative integer less than 109. In addition, if the implementation knows that its fixnum width is at least 40 bits, it can also check that the value of the seconds component is a fixnum.
(timespec-seconds
timespec)
Returns the seconds component of timespec.
The result must be the same (in the sense of eqv?
)
as the value passed to timespec
.
(timespec-nanoseconds
timespec)
Returns the nanoseconds component of timespec.
The result must be the same (in the sense of eqv?
)
as the value passed to timespec
.
(inexact->timespec
inexact)
Converts inexact into an approximate number of seconds and nanoseconds since the (unspecified) epoch and returns the results as a timespec object.
(timespec->inexact
timespec)
Returns an inexact number representing the seconds from the epoch to the value of timespec.
Note that these operations are not inverses, because inexact numbers typically do not have nanosecond precision.
(timespec=?
timespec1 timespec2)
Returns #t
if timespec1 and timespec2
represent the same instant of time, and #f
otherwise.
(timespec<?
timespec1 timespec2)
Returns #t
if timespec1 represents an earlier
instant of time than timespec2, and #f
otherwise.
Note that it is an (undetectable) error to compare two timespecs that are relative to different epochs.
(timespec-hash
timespec)
Returns an exact non-negative integer representing a hash code for timespec.
An implementation of SRFI 174 is in the repository of this SRFI. The files are:
srfi/174.sld
- uses a disjoint typechibi-tests.scm
- Tests using (chibi tests)
Note: A pair-based implementation is also available; simply
comment out the define-record-type
declaration
in srfi/174.sld
and remove the comment markers
from the declarations that follow.
Discussions between me, Lassi Kortela, and Harold Ancell, mostly on the SRFI 170 mailing list, made the need for this SRFI clear.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.