rfc3339.scm: RFC3339 Date and Time Format in Scheme

rfc3339.scm: RFC3339 Date and Time Format in Scheme

Version 0.2, 2005-12-05, `'

by Neil W. Van Dyke <>

     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 <>
     for details.  For other license options and consulting, contact
     the author.


The `rfc3339.scm' package implements parsing, formatting, and simple
validation of RFC3339 (
date and time format, which is a subset of ISO 8601
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
( 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.

           (make-rfc3339-record 1985 4 12 23 20 50 0.52 0))
          => (1985 4 12 23 20 50 0.52 0)


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)


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


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

           (string->rfc3339-record "1999-02")    #t)
          => (missing mday)

           (string->rfc3339-record "1999-02-29") #t)
          (invalid mday 29 (and (integer? mday)
                                (<= 1 mday (month-days year month))))

           (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

> (valid-full-rfc3339-record? rec)
     Yields a true value iff `check-rfc3339-record-full' yields a false

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))


The `rfc3339.scm' test suite can be enabled by editing the source code
file and loading Testeez (


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.