rfc3339.scm: RFC3339 Date and Time Format in Scheme
rfc3339.scm: RFC3339 Date and Time Format in Scheme
***************************************************
Version 0.2, 2005-12-05, `http://www.neilvandyke.org/rfc3339-scm/'
by Neil W. Van Dyke <neil@neilvandyke.org>
Copyright (C) 2005 Neil W. Van Dyke. This program is Free
Software; you can redistribute it and/or modify it under the terms
of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. This program is distributed in
the hope that it will be useful, but without any warranty; without
even the implied warranty of merchantability or fitness for a
particular purpose. See <http://www.gnu.org/copyleft/lesser.html>
for details. For other license options and consulting, contact
the author.
Introduction
************
The `rfc3339.scm' package implements parsing, formatting, and simple
validation of RFC3339 (ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt)
date and time format, which is a subset of ISO 8601
(http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html),
intended for use in Internet protocols.
Note that full Scheme support of ISO 8601 is a very different
project of the author, and not at all the intention of `rfc3339.scm'.
`rfc3339.scm' requires R5RS, SRFI-6, SRFI-9, and two particular
regular expression functions. Note that the regular expression
functions in Pregexp 1e9
(http://www.ccs.neu.edu/home/dorai/pregexp/pregexp.html) will not work,
but are expected to work in subsequent versions of Pregexp. Thus far,
`rfc3339.scm' has only been tested under PLT MzScheme.
Record Type
***********
`rfc3339-record' is an abstract data type for the information in an
RFC3339 format time and date. ("`rfc3339-string'" is used in
identifiers to denote the RFC3339 format as a Scheme string.)
> (make-rfc3339-record year month mday hour minute second)
secfrac offsetmin
Construct an `rfc3339-record' with the given field values. Each of
YEAR, MONTH, MDAY, HOUR, MINUTE, and SECOND is `#f' or a
nonnegative integer. SECFRAC is `#f' or a real number that is
greater than or equal to 0.0 and less than 1.0. OFFSETMIN is `#f'
or a nonnegative integer. Note that OFFSETMIN represents both the
hour and minute components of an RFC3339 string.
> (rfc3339-record? x)
Predicate for `rfc3339-record'.
> (rfc3339-record:year rec)
> (rfc3339-record:month rec)
> (rfc3339-record:mday rec)
> (rfc3339-record:hour rec)
> (rfc3339-record:minute rec)
> (rfc3339-record:second rec)
> (rfc3339-record:secfrac rec)
> (rfc3339-record:offsetmin rec)
Get the respective field value of `rfc3339-record' REC.
> (rfc3339-record:set-year! rec val)
> (rfc3339-record:set-month! rec val)
> (rfc3339-record:set-mday! rec val)
> (rfc3339-record:set-hour! rec val)
> (rfc3339-record:set-minute! rec val)
> (rfc3339-record:set-second! rec val)
> (rfc3339-record:set-secfrac! rec val)
> (rfc3339-record:set-offsetmin! rec val)
Set the respective field value of `rfc3339-record' REC to VAL.
> (rfc3339-record->list rec)
Yields a list of the `rfc3339-record' REC fields, corresponding to
the arguments of the `make-rfc3339-record' procedure.
(rfc3339-record->list
(make-rfc3339-record 1985 4 12 23 20 50 0.52 0))
=> (1985 4 12 23 20 50 0.52 0)
Parsing
*******
The parsing procedures are for constructing a `rfc3339-record's, lists,
and vectors from RFC3339 strings. The underlying parser can also apply
a user-supplied closure directly.
> (parse-rfc3339-string str constructor)
Parses RFC3339 string STR and applies procedure CONSTRUCTOR with
the parsed values. The arguments of CONSTRUCTOR are the same as
those of `make-rfc3339-record'.
> (string->rfc3339-record str)
Yields an `rfc3339-record' from RFC3339 string STR.
> (rfc3339-string->list str)
> (rfc3339-string->vector str)
Yields a list or vector (respectively) from the parsed values of
RFC3339 string STR. The list and vector elements correspond to
the arguments of `make-rfc3339-record'.
(rfc3339-string->list "1985-04-12T23:20:69.52+5:0")
=> (1985 4 12 23 20 69 0.52 300)
(rfc3339-string->vector "1985-04-12T23:20:69.52+5:0")
=> #(1985 4 12 23 20 69 0.52 300)
Formatting
**********
An RFC3339 string format can be obtained from an `rfc3339-record'.
> (write-rfc3339 rec port)
Write an RFC3339 string format of `rfc3339-record' REC to output
port PORT.
> (rfc3339-record->string rec)
Yield an RFC3339 string format of `rfc3339-record' REC as a Scheme
string.
Validation
**********
A few procedures are provided for validating `rfc3339-record's.
> (check-rfc3339-record-date rec explain?)
> (check-rfc3339-record-time rec explain?)
> (check-rfc3339-record-offset rec explain?)
Check the respective component of `rfc3339-record' REC for
completeness and correctness, yielding `#f' iff no problems were
detected. If EXPLAIN? is true, then true values of these
procedures are lists that "explain" the error detected. For
example:
(check-rfc3339-record-date
(string->rfc3339-record "1999-02") #t)
=> (missing mday)
(check-rfc3339-record-date
(string->rfc3339-record "1999-02-29") #t)
=>
(invalid mday 29 (and (integer? mday)
(<= 1 mday (month-days year month))))
(check-rfc3339-record-date
(string->rfc3339-record "2000-02-29") #t)
=> #f
Leap years are calculated correctly. Leap seconds (61st seconds in
minutes) are tolerated in any date and time.
> (check-rfc3339-record-full rec explain?)
Checks all three components. See `check-rfc3339-record-date' et
al.
> (valid-full-rfc3339-record? rec)
Yields a true value iff `check-rfc3339-record-full' yields a false
value.
SRFI-19 Interoperability
************************
`rfc3339.scm' has no dependency on SRFI-19, but a procedure is provided
for constructing a SRFI-19 `date'.
> (rfc3339-string->srfi19-date/constructor str make-date)
Contruct a SRFI-19 `date' from an RFC3339 string, where STR is the
string, and MAKE-DATE is the SRFI-19 `date' constructor.
Applications using SRFI-19 may wish to define an
`rfc3339-string->date' procedure:
(define (rfc3339-string->date str)
(rfc3339-string->srfi19-date/constructor str make-date))
Tests
*****
The `rfc3339.scm' test suite can be enabled by editing the source code
file and loading Testeez (http://www.neilvandyke.org/testeez/).
History
*******
Version 0.2 -- 2005-12-05
Release for PLT 299/3xx. Changed portability note in light of
Pregexp post-1e9 bug fix. Minor documentation changes.
Version 0.1 -- 2005-01-30
Initial release.