This is a WG2 proposal for date and time arithmetic, loosely based on Java's Joda Time functions. It's possible to implement SRFI 19 on top of it, but it provides much more flexibility.
For the purposes of this proposal, an instant is a rational number representing a particular second (or fraction thereof) of the Posix epoch, which began on 00:00:00 on 1 January 1970, Coordinated Universal Time but excludes all leap seconds. See TimeCowan for the current-posix-second procedure, which returns the current instant.
A chronology is a disjoint and immutable object that describes a particular calendar, such as the ISO, Gregorian, Julian, Jewish, Islamic, Persian, French Revolutionary, Maya, Chinese, Buddhist, Coptic, or Ethiopic calendar. Implementations MUST support the ISO chronology, and MAY support any of the other calendars mentioned here, or indeed any calendar not mentioned here.
Chronologies also incorporate the concept of time zone. An implementation MUST support the UTC (Universal Coordinated Time) timezone and any time zones expressible as a fixed offset in minutes from UTC. It SHOULD support the historical time zones of the tz database.
(default-chronology)
Returns the default system-dependent chronology, which may include time zone information.
(chronology symbol)
Return a chronology named by symbol. The ISO chronology is named iso. If provided, the Gregorian chronology is named gregorian and the Julian chronology is named julian. The names of other chronologies are system-dependent. The chronologies returned by this procedure are in the UTC time zone.
(chronology-names)
Returns a list of the symbols naming the chronologies provided by the implementation. It is an error to modify this list.
(chronology-name chronology)
Returns the symbol that names chronology.
(chronology? obj)
Returns #t if obj is a chronology and #f otherwise.
(chronology-with-time-zone chronology timezone)
Returns a chronology object based on chronology, but with the time zone specified by timezone. If timezone is an integer, it represents the number of minutes ahead of UTC. If the implementation supports the tz database, and timezone is a string containing a time zone name defined by that database, it represents the time zone with that name. Otherwise, the interpretation of timezone is implementation-dependent.
(chronology-time-zone chronology)
When chronology was returned from chronology, returns 0. When chronology was returned from chronology-with-time-zone, returns the time zone value which was specified to that procedure.
(chronology-standard-time-offset chronology)
Returns the standard time zone offset in minutes from UTC corresponding to this chronology. This is always numeric, even if chronology was created using a non-numeric time zone.
(make-compound-chronology chronology1 chronology2 instant)
Returns a chronology that uses chronology2 at all times before instant, and chronology1 for all times including and following instant. This is useful for constructing chronologies that transition from Julian to Gregorian at a specified date.
A date object is a member of an immutable disjoint type that specifies information about a date or time with respect to a certain chronology. For example, with respect to the ISO, Gregorian, or Julian chronologies, a date may represent a specific year, a specific week of a specific year, or an instant in time precise to a second or better. On the other hand, a date object may contain just a particular month. Date objects have multiple numeric-valued fields such as year or minute-of-day, whose meanings and possible values are determined by the chronology.
(make-date chronology alist)
Constructs and returns a date object using chronology. Alist is an association list mapping symbols which are names of fields meaningful to chronology to associated numeric values. An error is signaled if the field values are invalid or inconsistent.
(date? obj)
Returns #t if obj is a date object, and #f otherwise.
(instant->date instant chronology)
Constructs and returns a date object using chronology and corresponding to instant.
(date->instant date)
Return the instant corresponding to date, provided there is enough information in the fields of date to uniquely determine it; otherwise return #f.
(date->alist date)
Constructs and returns an alist containing the fields of date. Implementations SHOULD provide computed fields as well as explicitly set ones.
(date-field date fieldname)
Returns the numeric value of the field named fieldname (a symbol) within date, or #f if there is no such field. If the specified field was not provided when date was constructed, and it is possible to compute its value from the values of fields that were provided, the value is computed and returned.
(date-update date fieldname value)
Constructs and returns a new date object based on date, but with the field named fieldname updated to value. An error is signaled if the field is unknown or the value is out of range.
(date-increment date fieldname increment)
Constructs and returns a new date object which is later than date by increment measured in the units specified by fieldname, or earlier if increment is negative. Returns #f if an appropriate date object cannot be constructed due to lack of information in date An error is signaled if fieldname is unknown.
For example, (date-increment date 'day-of-month 7) adds seven days to date (which is typically the same as one week, but may be different in some chronologies).
(date-chronology date)
Returns the chronology associated with date.
(date-field-maximum date fieldname)
(date-field-minimum date fieldname)
Returns the maximum or minimum legal value of the field named fieldname in the chronology associated with date. This value is not necessarily the same for all instants; for example, 28 is the maximum value of day-of-month if month has the value 2 (February).
(date-round date fieldname)
(date-ceiling date fieldname)
(date-floor date fieldname)
(date-truncate date fieldname)
Constructs and returns a new date object which is the same as date, but adjusted to the nearest integral value of fieldname using the round, ceiling, floor, or truncate functions. This may cause other fields to change their values as well.
Unless otherwise noted, the values of these fields are exact integers. These fields may be relevant to other chronologies as well.