srfi-19

Time Data Types and Procedures

This is a Chicken port of SRFI-19. This document describes the original SRFI API (SRFI-19) and the extensions (*).

  1. srfi-19
    1. Abstract
    2. Specification
  2. Documentation
    1. Usage
    2. Time
      1. Constants
        1. time-duration
        2. time-monotonic
        3. time-process
        4. time-tai
        5. time-thread
        6. time-utc
      2. Current time and clock resolution
        1. current-time
        2. monotonic-time (*)
        3. utc-time (*)
        4. tai-time (*)
        5. gc-time (*)
        6. process-time (*)
        7. thread-time (*)
        8. time-resolution
      3. Time object and accessors
        1. make-time
        2. make-time* (*)
        3. time?
        4. time-type
        5. time-nanosecond
        6. time-second
        7. set-time-type!
        8. set-time-nanosecond!
        9. set-time-second!
        10. time-hash (*)
        11. copy-time
        12. time-copy (*)
      4. Time comparison procedures
        1. time-compare (*)
        2. time-min (*)
        3. time-max (*)
        4. time<=?
        5. time<?
        6. time=?
        7. time>=?
        8. time>?
      5. Time arithmetic procedures
        1. one-second-duration (*)
        2. one-nanosecond-duration (*)
        3. zero-time (*)
        4. time-difference
        5. time-difference!
        6. add-duration
        7. add-duration!
        8. subtract-duration
        9. subtract-duration!
        10. divide-duration (*)
        11. divide-duration! (*)
        12. multiply-duration (*)
        13. multiply-duration! (*)
        14. time-negative? (*)
        15. time-positve? (*)
        16. time-zero? (*)
        17. time-abs (*)
        18. time-abs! (*)
        19. time-negate (*)
        20. time-negate! (*)
      6. Time Conversion (*)
        1. seconds->time
        2. time->nanoseconds
        3. nanoseconds->time
        4. nanoseconds->seconds
        5. time->milliseconds
        6. milliseconds->time
        7. milliseconds->seconds
        8. time->date
        9. time->julian-day
        10. time->modified-julian-day
      7. SRFI-18 Time (*)
        1. time->srfi-18-time
        2. srfi-18-time->time
    3. Date
    4. Types
      1. Current date
        1. current-date
        2. current-julian-day
        3. current-modified-julian-day
      2. Date object and accessors
        1. default-date-clock-type
        2. make-date (extended)
        3. copy-date (*)
        4. date-copy (*)
        5. date?
        6. date-nanosecond
        7. date-second
        8. date-minute
        9. date-hour
        10. date-day
        11. date-month
        12. date-year
        13. date-zone-offset
        14. date-zone-name (*)
        15. date-dst? (*)
        16. date-year-day
        17. date-week-day
        18. date-week-number
        19. leap-year? (*)
        20. leap-day? (*)
      3. Time/Date/Julian Day/Modified Julian Day Converters
        1. seconds->date
        2. date->seconds (*)
        3. date->time (*)
        4. date->julian-day
        5. date->modified-julian-day
        6. date->time-monotonic
        7. date->time-tai
        8. date->time-utc
        9. julian-day->date
        10. julian-day->time-monotonic
        11. julian-day->time-tai
        12. julian-day->time-utc
        13. modified-julian-day->date
        14. modified-julian-day->time-monotonic
        15. modified-julian-day->time-tai
        16. modified-julian-day->time-utc
        17. time-monotonic->date
        18. time-monotonic->julian-day
        19. time-monotonic->modified-julian-day
        20. time-monotonic->time-tai
        21. time-monotonic->time-tai!
        22. time-monotonic->time-utc
        23. time-monotonic->time-utc!
        24. time-tai->date
        25. time-tai->julian-day
        26. time-tai->modified-julian-day
        27. time-tai->time-monotonic
        28. time-tai->time-monotonic!
        29. time-tai->time-utc
        30. time-tai->time-utc!
        31. time-utc->date
        32. time-utc->julian-day
        33. time-utc->modified-julian-day
        34. time-utc->time-monotonic
        35. time-utc->time-monotonic!
        36. time-utc->time-tai
        37. time-utc->time-tai!
      4. Date Arithmetic (*)
        1. date-difference
        2. date-add-duration
        3. date-subtract-duration
        4. date-adjust
        5. date-adjust*
      5. Date Comparison (*)
        1. date-compare
        2. date-hash
        3. date=?
        4. date>?
        5. date<?
        6. date>=?
        7. date<=?
        8. read-leap-second-table
    5. Timezone (*)
      1. local-timezone-locale
      2. utc-timezone-locale
      3. timezone-locale-name
      4. timezone-locale-offset
      5. timezone-locale-dst?
    6. Date to String/String to Date Converters (Input/Output Procedures)
      1. format-date (*)
      2. scan-date (*)
      3. date->string
      4. string->date
      5. DATE->STRING conversion specifiers
      6. STRING->DATE conversion specifiers
    7. Date/Time Literals (*)
      1. Usage
        1. date-literal-form
        2. time-literal-form
        3. read-date-literal
        4. write-date-literal
    8. Time Period (*)
      1. Usage
        1. make-time-period
        2. time-period-copy
        3. time-period-begin
        4. time-period-end
        5. time-period-last
        6. time-period-type
        7. time-period?
        8. time-period-duration
        9. time-period-hash
        10. time-period-compare
        11. time-period=?
        12. time-period<?
        13. time-period>?
        14. time-period<=?
        15. time-period>=?
        16. time-period-preceding
        17. time-period-succeeding
        18. time-period-contains/period?
        19. time-period-contains/time?
        20. time-period-contains/date?
        21. time-period-contains?
        22. time-period-intersects?
        23. time-period-intersection
        24. time-period-union
        25. time-period-span
        26. time-period-shift
        27. time-period-shift!
  3. SRFI 29 bundles
  4. Examples
  5. Notes
  6. Bugs and Limitations
  7. Requirements
  8. Author
  9. Repository
  10. Acknowledgments
  11. Version history
  12. License

Abstract

Points in time are represented as the number of seconds (with nanosecond precision) since "the epoch," a zero point in time. Several standard variants are defined, including UTC (universal coordinated time), TAI (international atomic time), and monotonic time. A point in time can also be represented as a Julian Day or Modified Julian Day number. Time durations, including time spent in a process or thread, are defined. Conversion routines are provided. The procedure CURRENT-TIME queries the current time in a specified variant, with a system-dependent resolution. Procedures for time arithmetic and time comparisons are also provided.

A date is a representation of a point in time in the Gregorian calendar, a 24 hour clock (with nanosecond precision) and a time zone offset from UTC. Procedures for converting between time and dates are provided, as well as for reading and writing string representations of dates.

Specification

A Time object, which is distinct from all existing types, defines a point in time or a time duration in some standard time system. The standard time systems are:

Time duration.

A time object consists of three components:

A Date object, which is distinct from all existing types, represents a point in time as represented by the Gregorian calendar as well as by a time zone. Dates are immutable. A date consists of the following components:

A Julian Day represents a point in time as a real number of days since -4713-11-24T12:00:00Z (midday UT on 24 November 4714 BC in the proleptic Gregorian calendar (1 January 4713 BC in the proleptic Julian calendar)).

A Modified Julian Day represents a point in time as a real number of days since 1858-11-17T00:00:00Z (midnight UT on 17 November AD 1858).

A tz-offset value follows ISO 8601; positive for east of UTC, and negative for west. This is the opposite of the POSIX TZ environment variable.

Where the SRFI-19 document states a tz-offset argument a timezone-components object is also legal; see Timezone

Documentation

Usage

(import srfi-19)
(import srfi-19-core)

Time

(import srfi-19-time)

Constants

time-duration
[constant] (time-duration)

Symbol representing Time duration.

time-monotonic
[constant] (time-monotonic)

Symbol representing monotonic time.

time-process
[constant] (time-process)

Symbol representing time spent in current process.

time-tai
[constant] (time-tai)

Symbol representing TAI time.

time-thread
[constant] (time-thread)

Symbol representing time spent in current thread.

time-utc
[constant] (time-utc)

Current time and clock resolution

current-time
[procedure] (current-time [TIME-TYPE]) -> time

Current time, of type time-type system, which defaults to TIME-UTC.

monotonic-time (*)
utc-time (*)
tai-time (*)
gc-time (*)
process-time (*)
thread-time (*)
[procedure] (monotonic-time [SECS | NS SEC]) -> time
[procedure] (utc-time [SECS | NS SEC]) -> time
[procedure] (tai-time [SECS | NS SEC]) -> time
[procedure] (gc-time [SECS | NS SEC]) -> time
[procedure] (process-time [SECS | NS SEC]) -> time
[procedure] (thread-time [SECS | NS SEC]) -> time

Returns like:

<none>
(current-time <time-type>).
SECS
(seconds->time SECS <time-type>).
NS SEC
(make-time <time-type> NS SEC).

From Chibi (srfi 19), with extensions.

time-resolution
[procedure] (time-resolution [TIME-TYPE]) -> integer

Clock resolution, in nanoseconds, of the system clock of type type time-type system, which defaults to TIME-UTC.

Time object and accessors

make-time
[procedure] (make-time TYPE NANOSECOND SECOND) -> time

Creates a time object.

make-time* (*)
[procedure] (make-time* [weeks: 0] [days: 0] [hours: 0] [minutes: 0] [seconds: 0] [milliseconds: 0] [microseconds: 0] [nanoseconds: 0] [time-type: duration]) -> time

Returns a time-object of clock-type time-type where the seconds and nanoseconds values are calculated by summing the keyword arguments.

time?
[procedure] (time? OBJECT) -> boolean

#t if object is a time object, otherwise, #f.

time-type
[procedure] (time-type TIME) -> time-type

Time type.

time-nanosecond
[procedure] (time-nanosecond TIME) -> integer

Time nanosecond.

time-second
[procedure] (time-second TIME) -> integer

Time second.

set-time-type!
[procedure] (set-time-type! TIME TIME-TYPE)

Changes time type. Note: This changes the semantics of the time object. To convert a time to another system of representation, use one of the conversion procedures.

set-time-nanosecond!
[procedure] (set-time-nanosecond! TIME INTEGER)

Changes time nanosecond.

set-time-second!
[procedure] (set-time-second! TIME INTEGER)

Changes time second.

time-hash (*)
[procedure] (time-hash TIME [BOUND]) -> fixnum

Hash value for TIME within BOUND.

copy-time
time-copy (*)
[procedure] (copy-time TIME) -> time2
[procedure] (time-copy TIME) -> time

Creates a new time, with the same time type, nanosecond, and second as TIME.

Time comparison procedures

All of the time comparison procedures require the time objects to be of the same type. It is an error to use these procedures on time objects of different types. For the point-in-time measurements (e.g., TIME-TAI and TIME-UTC), the semantics are described in plain text. For durations, (e.g., TIME-DURATION, TIME-CPU, the semantics are described in parentheses.

time-compare (*)
[procedure] (time-compare TIME1 TIME2) -> integer

Returns -1, 0, or +1.

time-min (*)
time-max (*)
[procedure] (time-min TIME1 [TIME2...]) -> time
[procedure] (time-max TIME1 [TIME2...]) -> time

Returns the minimum/maximum time object from TIME1 TIME2....

time<=?
[procedure] (time<=? TIME1 TIME2) -> boolean

#t if time1 is before or at (less than or equal to) time2, #f otherwise.

time<?
[procedure] (time<? TIME1 TIME2) -> boolean

#t if time1 is before (less than) time2, #f otherwise.

time=?
[procedure] (time=? TIME1 TIME2) -> boolean

#t if time1 at (equal) time2, #f otherwise.

time>=?
[procedure] (time>=? TIME1 TIME2) -> boolean

#t if time1 is at or after (greater than or equal to) time2, #f otherwise.

time>?
[procedure] (time>? TIME1 TIME2) -> boolean

#t if time1 is after (greater than) time2, #f otherwise.

Time arithmetic procedures

one-second-duration (*)
[procedure] (one-second-duration) -> time
one-nanosecond-duration (*)
[procedure] (one-nanosecond-duration) -> time
zero-time (*)
[procedure] (zero-time [TIME-TYPE time-duration]) -> time

Returns a 0 valued time of TIME-TYPE.

TIME-TYPE
(or time-tai time-utc time-monotonic time-thread time-process time-duration time-gc\)
time-difference
time-difference!
[procedure] (time-difference TIME1 TIME2) -> time-duration
[procedure] (time-difference! TIME1 TIME2) -> time-duration

The TIME-DURATION between time1 and time2. It is an error if time1 and time2 are of different time types.

add-duration
add-duration!
[procedure] (add-duration TIME1 TIME-DURATION) -> time
[procedure] (add-duration! TIME1 TIME-DURATION) -> time

The time resulting from adding time-duration to time1, which is a time object of the same time type as time1.

subtract-duration
subtract-duration!
[procedure] (subtract-duration TIME1 TIME-DURATION) -> time
[procedure] (subtract-duration! TIME1 TIME-DURATION) -> time

The time resulting from subtracting time-duration to time1, which is a time object of the same time type as time1.

divide-duration (*)
divide-duration! (*)
[procedure] (divide-duration DURATION REAL) -> time
[procedure] (divide-duration! DURATION REAL) -> time

Returns a duration, from DURATION, divided by REAL, without remainder.

multiply-duration (*)
multiply-duration! (*)
[procedure] (multiply-duration DURATION REAL) -> time
[procedure] (multiply-duration! DURATION REAL) -> time

Returns a duration, from DURATION, multiplied by REAL, truncated.

time-negative? (*)
time-positve? (*)
time-zero? (*)
[procedure] (time-negative? TIME) -> boolean
[procedure] (time-positve? TIME) -> boolean
[procedure] (time-zero? TIME) -> boolean

Is TIME negative/positive/zero?

nonoseconds seconds where +/- - is negative, +/- + is positive, & 0 0 is zero.

time-abs (*)
time-abs! (*)
[procedure] (time-abs TIME) -> time
[procedure] (time-abs! TIME) -> time

Returns the absolute time value, from TIME.

time-negate (*)
time-negate! (*)
[procedure] (time-negate TIME) -> time
[procedure] (time-negate! TIME) -> time

Returns the sign inverted time value, from TIME.

Only time-second participates.

Time Conversion (*)

seconds->time
[procedure] (seconds->time SECONDS [TIME-TYPE time-duration]) -> time

Converts a SECONDS value, may be fractional, into a TIME-TYPE time object.

time->nanoseconds
[procedure] (time->nanoseconds TIME) -> integer

Returns the TIME object value as a nanoseconds value.

nanoseconds->time
[procedure] (nanoseconds->time NANOSECONDS [TIME-TYPE time-duration]) -> time

Returns the NANOSECONDS value as a time TIME-TYPE object.

nanoseconds->seconds
[procedure] (nanoseconds->seconds NANOSECONDS) -> real

Returns the NANOSECONDS value as a seconds value.

time->milliseconds
[procedure] (time->milliseconds TIME) -> integer

Returns the TIME object value as a milliseconds value.

milliseconds->time
[procedure] (milliseconds->time MILLISECONDS [TIME-TYPE time-duration]) -> time

Returns the MILLISECONDS value as a time TIME-TYPE object.

milliseconds->seconds
[procedure] (milliseconds->seconds MILLISECONDS) -> real

Returns the MILLISECONDS value as a seconds value.

time->date
[procedure] (time->date TIME) -> date

Returns the TIME object value as a date. A shorthand for the (time-*->date...) procedures.

time->julian-day
[procedure] (time->julian-day TIME) -> real

Returns the julian day for the TIME object.

time->modified-julian-day
[procedure] (time->modified-julian-day TIME) -> real

Returns the modified julian day for the TIME object.

SRFI-18 Time (*)

Note that the SRFI-18 identifiers time?, current-time, seconds->time, time->seconds, milliseconds->time, and time->milliseconds are in conflict with those of SRFI-19.

time->srfi-18-time
[procedure] (time->srfi-18-time TIME) -> srfi-18#time

Converts a SRFI-19 time object to a SRFI-18 time object. The conversion is really only meaningful for time-duration, but any time-type is accepted.

srfi-18-time->time
[procedure] (srfi-18-time->time TIME) -> srfi-19#time

Converts a SRFI-18 time object into a SRFI-19 time-duration object.

Date

(import srfi-19-date)

Types

TIMEZONE-INFO is a tz-offset, a boolean where #t is (local-timezone-locale) & #f is (utc-timezone-locale), or a timezone-components.

Current date

current-date
[procedure] (current-date [TZ-OFFSET]) -> date

Date corresponding to the current UTC time.

current-julian-day
[procedure] (current-julian-day) -> real

Current Julian Day.

current-modified-julian-day
[procedure] (current-modified-julian-day) -> real

Current Modified Julian Day.

Date object and accessors

Date objects are immutable once created.

default-date-clock-type
[parameter] (default-date-clock-type [CLOCK-TYPE time-utc]) -> symbol

Sets or gets the clock-type used by default for conversion of a date to a time.

make-date (extended)
[procedure] (make-date NANOSECOND SECOND MINUTE HOUR DAY MONTH YEAR [ZONE-OFFSET [TZ-NAME [DST-FLAG]]]) -> date

Same as SRFI-19 except for the optional parameters and allowing a timezone-components object for the ZONE-OFFSET.

The ZONE-OFFSET is an integer or timezone-components. Default is the (timezone-locale-offset), the current locale timezone offset.

The TZ-NAME is a string or #f, and is the timezone name. Default is #f.

The DST-FLAG is a boolean, and indicates whether Day Saving TIme (or Summer Time) is active. Default is #f.

When the ZONE-OFFSET is a timezone-components object the TZ-NAME and DST-FLAG are pulled from the timezone-components, unless explicitly supplied.

copy-date (*)
date-copy (*)
[procedure] (copy-date DATE) -> date
[procedure] (date-copy DATE) -> date

Returns an exact copy of the specified DATE object.

date?
[procedure] (date? DATE) -> boolean

#t if object is a time object, otherwise, #f.

date-nanosecond
[procedure] (date-nanosecond DATE) -> integer

Date nanosecond.

date-second
[procedure] (date-second DATE) -> integer

Date second.

date-minute
[procedure] (date-minute DATE) -> integer

Date minute.

date-hour
[procedure] (date-hour DATE) -> integer

Date hour.

date-day
[procedure] (date-day DATE) -> integer

Date day.

date-month
[procedure] (date-month DATE) -> integer

Date month.

date-year
[procedure] (date-year DATE) -> integer

Date year.

date-zone-offset
[procedure] (date-zone-offset DATE) -> integer

Date time zone offset.

date-zone-name (*)
[procedure] (date-zone-name DATE) -> boolean
[procedure] (date-zone-name DATE) -> string

Returns the timezone abbreviation of the specified DATE object. The result is either a string or #f.

date-dst? (*)
[procedure] (date-dst? DATE) -> boolean

Returns the daylight saving time flag of the specified DATE object.

Only valid for "current" dates. Historical dates will not have a correct setting. Future dates cannot have a correct setting.

date-year-day
[procedure] (date-year-day DATE) -> integer

The ordinal day of the year of this date. January 1 is 1, etc.

date-week-day
[procedure] (date-week-day DATE) -> integer

The day of the week of this date, where Sunday=0, Monday=1, etc.

date-week-number
[procedure] (date-week-number DATE DAY-OF-WEEK-STARTING-WEEK) -> integer

The ordinal week of the year which holds this date, ignoring a first partial week. 'Day-of-week-starting-week' is the integer corresponding to the day of the week which is to be considered the first day of the week (Sunday=0, Monday=1, etc.).

leap-year? (*)
[procedure] (leap-year? YEAR) -> boolean

Is the specified YEAR a leap year?

YEAR
(or fixnum date) ; numeric year or date object.
leap-day? (*)
[procedure] (leap-day? DATE) -> boolean

Is the specified DATE a leap day?

The leap day of the leap month of a leap year.

Time/Date/Julian Day/Modified Julian Day Converters

seconds->date
[procedure] (seconds->date SECONDS [TZ-OFFSET #t]) -> date

Converts a SECONDS value, which may be fractional, into a date object.

SECONDS is relative to 00:00:00 January 1, 1970 UTC.

date->seconds (*)
[procedure] (date->seconds DATE [CLOCK-TYPE (default-date-clock-type)]) -> real

Returns the specified DATE as as a seconds value, based on the CLOCK-TYPE.

The seconds value is relative to the TAI-EPOCH - 1 January 1970 CE at 00:00:00 UTC.

date->time (*)
[procedure] (date->time DATE [CLOCK-TYPE (default-date-clock-type)]) -> time

Returns the specified DATE as a time-object of type CLOCK-TYPE.

date->julian-day
[procedure] (date->julian-day DATE) -> jd

Convert date to Julian Day.

date->modified-julian-day
[procedure] (date->modified-julian-day DATE) -> mjd

Convert date to Modified Julian Day.

date->time-monotonic
[procedure] (date->time-monotonic DATE) -> time-monotonic

Convert date to monotonic time.

date->time-tai
[procedure] (date->time-tai DATE) -> time-tai

Convert date to TAI time.

date->time-utc
[procedure] (date->time-utc DATE) -> time-utc

Convert date to UTC time.

julian-day->date
[procedure] (julian-day->date JD [TZ-OFFSET]) -> date

Convert Julian Day to date, , using time zone offset, which defaults to the local time zone.

julian-day->time-monotonic
[procedure] (julian-day->time-monotonic JD) -> time-monotonic

Convert Julian Day to monotonic time.

julian-day->time-tai
[procedure] (julian-day->time-tai JD) -> time-tai

Convert Julian Day to TAI time.

julian-day->time-utc
[procedure] (julian-day->time-utc JD) -> time-utc

Convert Julian Day to UTC time.

modified-julian-day->date
[procedure] (modified-julian-day->date MJD [TZ-OFFSET]) -> date

Convert Modified Julian Day to date, using time zone offset, which defaults to the local time zone.

modified-julian-day->time-monotonic
[procedure] (modified-julian-day->time-monotonic MJD) -> time-monotonic

Convert Modified Julian Day to monotonic time.

modified-julian-day->time-tai
[procedure] (modified-julian-day->time-tai MJD) -> time-tai

Convert Modified Julian Day to TAI time.

modified-julian-day->time-utc
[procedure] (modified-julian-day->time-utc MJD) -> time-utc

Convert Modified Julian Day to UTC time.

time-monotonic->date
[procedure] (time-monotonic->date TIME-MONOTONIC [TZ-OFFSET]) -> date

Convert monotonic time to date, using time zone offset, which defaults to the local time zone.

time-monotonic->julian-day
[procedure] (time-monotonic->julian-day TIME-MONOTONIC) -> jd

Convert monotonic time to Julian Day.

time-monotonic->modified-julian-day
[procedure] (time-monotonic->modified-julian-day TIME-MONOTONIC) -> mjd

Convert monotonic time to Modified Julian Day.

time-monotonic->time-tai
[procedure] (time-monotonic->time-tai TIME-MONOTONIC) -> time-tai

Convert monotonic time to TAI time.

time-monotonic->time-tai!
[procedure] (time-monotonic->time-tai! TIME-MONOTONIC) -> time-tai

Convert monotonic time to TAI time. The time structure may be reused.

time-monotonic->time-utc
[procedure] (time-monotonic->time-utc TIME-MONOTONIC) -> time-utc

Convert monotonic time to UTC time.

time-monotonic->time-utc!
[procedure] (time-monotonic->time-utc! TIME-MONOTONIC) -> time-utc

Convert monotonic time to UTC time. The time structure may be reused.

time-tai->date
[procedure] (time-tai->date TIME-TAI [TZ-OFFSET]) -> date

Convert TAI time to date, using time zone offset, which defaults to the local time zone.

time-tai->julian-day
[procedure] (time-tai->julian-day TIME-TAI) -> jd

Convert TAI time to Julian Day.

time-tai->modified-julian-day
[procedure] (time-tai->modified-julian-day TIME-TAI) -> mjd

Convert TAI time to Modified Julian Day.

time-tai->time-monotonic
[procedure] (time-tai->time-monotonic TIME-TAI) -> time-monotonic

Convert TAI time to monotonic time.

time-tai->time-monotonic!
[procedure] (time-tai->time-monotonic! TIME-TAI) -> time-monotonic

Convert TAI time to monotonic time. The time structure may be reused.

time-tai->time-utc
[procedure] (time-tai->time-utc TIME-TAI) -> time-utc

Convert TAI time to monotonic time.

time-tai->time-utc!
[procedure] (time-tai->time-utc! TIME-TAI) -> time-utc

Convert TAI time to monotonic time. The time structure may be reused.

time-utc->date
[procedure] (time-utc->date TIME-UTC [TZ-OFFSET]) -> time-utc

Convert UTC time to date, using time zone offset, which defaults to the local time zone.

time-utc->julian-day
[procedure] (time-utc->julian-day TIME-UTC) -> jd

Convert UTC time to Julian Day

time-utc->modified-julian-day
[procedure] (time-utc->modified-julian-day TIME-UTC) -> mjd

Convert UTC time to Modified Julian Day.

time-utc->time-monotonic
[procedure] (time-utc->time-monotonic TIME-UTC) -> time-monotonic

Convert UTC time to monotonic time.

time-utc->time-monotonic!
[procedure] (time-utc->time-monotonic! TIME-UTC) -> time-monotonic

Convert UTC time to monotonic time. The time structure may be reused.

time-utc->time-tai
[procedure] (time-utc->time-tai TIME-UTC) -> time-tai

Convert UTC time to TAI time.

time-utc->time-tai!
[procedure] (time-utc->time-tai! TIME-UTC) -> time-tai

Convert UTC time to TAI time. The time structure may be reused.

Date Arithmetic (*)

date-difference
[procedure] (date-difference DATE1 DATE2 [CLOCK-TYPE]) -> time

Returns the time-duration between DATE1 and DATE2.

date-add-duration
[procedure] (date-add-duration DATE DURATION [CLOCK-TYPE]) -> date

Returns a new date, the DATE plus the DURATION.

date-subtract-duration
[procedure] (date-subtract-duration DATE DURATION [CLOCK-TYPE]) -> date

Returns a new date, the DATE minus the DURATION.

date-adjust
[procedure] (date-adjust DATE AMOUNT KEY [CLOCK-TYPE]) -> date

Returns a new date, the DATE adjusted by the AMOUNT of KEY.

AMOUNT
integer ;
KEY
symbol ; '(years quarters months weeks days hours minutes seconds milliseconds microseconds nanoseconds).

If the day of the month of DATE is greater than the number of days in the final month, the day of the month will change to the last day in the final month.

Adjusting a time KEY (ex: 'hours) follows the semantics of date-add-duration.

date-adjust*
[procedure] (date-adjust* DATE KEY AMOUNT ... [CLOCK-TYPE]) -> date

Returns a new date, the DATE adjusted by each of the KEY AMOUNT pairs, in-order.

AMOUNT
integer ;
KEY
keyword ; '(years: quarters: months: weeks: days: hours: minutes: seconds: milliseconds: microseconds: nanoseconds).:

A convenience wrapper of date-adjust.

Date Comparison (*)

date-compare
[procedure] (date-compare DATE1 DATE2) -> integer

Returns -1, 0, or +1.

date-hash
[procedure] (date-hash DATE [BOUND]) -> fixnum

Hash value for DATE within BOUND.

date=?
[procedure] (date=? DATE1 DATE2) -> boolean

Is DATE1 on DATE2?

date>?
[procedure] (date>? DATE1 DATE2) -> boolean

Is DATE1 after DATE2?

date<?
[procedure] (date<? DATE1 DATE2) -> boolean

Is DATE1 before DATE2?

date>=?
[procedure] (date>=? DATE1 DATE2) -> boolean

Is DATE1 after or on DATE2?

date<=?
[procedure] (date<=? DATE1 DATE2) -> boolean

Is DATE1 before or on DATE2?

read-leap-second-table
[procedure] (read-leap-second-table FILENAME)

Sets the leap second table from the specified FILENAME.

The file format is the same as the "tai-utc.dat" file in the distribution. Provided by the U.S. Naval Observatory.

Timezone (*)

The daylight saving time (summer time) flag is always taken from the system (locale egg) unless supplied. Any summer time rule component of a timezone-components object is not processed.

TZ-COMPONENTS
timezone-components ;a timezone object

SRFI-19 timezone offset follows ISO 8601; positive for east of UTC, and negative for west. This is the opposite of the POSIX TZ environment variable.

(import srfi-19-timezone)

local-timezone-locale

[parameter] (local-timezone-locale [TZ-COMPONENTS])

Gets or sets the local timezone-locale object.

utc-timezone-locale

[parameter] (utc-timezone-locale [TZ-COMPONENTS])

Gets or sets the utc timezone-locale object.

Not a good idea to change the value.

timezone-locale-name

[procedure] (timezone-locale-name [TZ-COMPONENTS]) -> symbol

Returns the timezone-locale name of the supplied TZ-COMPONENTS, or the (local-timezone-locale) if missing.

timezone-locale-offset

[procedure] (timezone-locale-offset [TZ-COMPONENTS]) -> integer

Returns the timezone-locale offset of the supplied TZ-COMPONENTS, or the (local-timezone-locale) if missing.

timezone-locale-dst?

[procedure] (timezone-locale-dst? [TZ-COMPONENTS]) -> boolean

Returns the timezone-locale daylight saving time flag of the supplied TZ-COMPONENTS, or the (local-timezone-locale) if missing.

Date to String/String to Date Converters (Input/Output Procedures)

(import srfi-19-io)

format-date (*)

[procedure] (format-date DESTINATION DATE-FORMAT DATE)
[procedure] (format-date DATE-FORMAT DATE) -> {{string}}

Displays a text form of the DATE on the DESTINATION using the DATE-FORMAT.

DESTINATION
; the result is returned as a string.
DESTINATION
#f ; the result is returned as a string.
DESTINATION
#t ; the (current-output-port) is used.
DESTINATION
output-port ; text output port.
DESTINATION
number ; the (current-error-port) is the DESTINATION.

scan-date (*)

[procedure] (scan-date SOURCE TEMPLATE) -> date

Reads a text form of a date from the SOURCE, following the TEMPLATE, and returns a date object.

SOURCE
#t ; (current-input-port).
SOURCE
input-port ; text input port.
SOURCE
string ; a date text form.

A partial date resulting from a time-only format, missing the d-m-y, is completed with from the (current-date), as is any timezone information, and missing h:m:s:ns are 0.

date->string

[procedure] (date->string DATE [DATE-FORMAT]) -> date
DATE
date
DATE-FORMAT
string ; default "~c".

string->date

[procedure] (string->date SOURCE [TEMPLATE]) -> date
SOURCE
see scan-date.
TEMPLATE
string ; default (localized-template/default 'srfi-19 'date-time).

The string->date procedure allows the template-name argument to be optional. When missing the locale's date-time-format string is used. The supplied locale bundle's strings are invertible.

DATE->STRING conversion specifiers

Ch Conversion
~~ a literal ~
~a locale's abbreviated weekday name (Sun...Sat)
~A locale's full weekday name (Sunday...Saturday)
~b locale's abbreviate month name (Jan...Dec)
~B locale's full month day (January...December)
~c locale's date and time (e.g., "Fri Jul 14 20:28:42-0400 2000")
~d day of month, zero padded (01...31)
~D date (mm/dd/yy)
~e day of month, blank padded ( 1...31)
~f seconds+fractional seconds, using locale's decimal separator (e.g. 5.2).
~g day of month
~h same as ~b
~H hour, zero padded, 24-hour clock (00...23)
~I hour, zero padded, 12-hour clock (01...12)
~j day of year, zero padded
~k hour, blank padded, 24-hour clock ( 0...23)
~l hour, blank padded, 12-hour clock ( 1...12)
~m month, zero padded (01...12)
~M minute, zero padded (00...59)
~n new line
~N nanosecond, zero padded
~p locale's AM or PM
~r time, 12 hour clock, same as "~I:~M:~S ~p"
~s number of full seconds since "the epoch" (in UTC)
~S second, zero padded (00...60)
~t horizontal tab
~T time, 24 hour clock, same as "~H:~M:~S"
~u day ordinal suffix
~U week number of year with Sunday as first day of week (00...53)
~V ISO 8601 week number of the year with Monday as first day of week (01..53)
~w day of week (0...6)
~W week number of year with Monday as first day of week (01...52)
~x locale's date representation
~X locale's time representation
~y last two digits of year (00...99)
~Y 4-digit year
~z time zone in RFC-822 style
~Z symbol time zone (not-implemented)
~1 ISO-8601 year-month-day format
~2 ISO-8601 hour-minute-second-timezone format
~3 ISO-8601 hour-minute-second format
~4 ISO-8601 year-month-day-hour-minute-second-timezone format
~5 ISO-8601 year-month-day-hour-minute-second format

The normally zero-padded conversions f, H, I, j, m, M, N, S, y have a padding character override feature. If the tilde is followed by a - then padding is suppressed. If followed by a _ the space character is used for padding. Otherwise, the default, zero-padding is perfomed.

g & u from Chibi (srfi 19).

STRING->DATE conversion specifiers

Ch Skip to Read Set
~~ any read literal ~
~a char-alphabetic? abbreviated weekday in locale nothing
~A char-alphabetic? full weekday in locale nothing
~b char-alphabetic? abbreviated month name in locale nothing
~B char-alphabetic? full month name in locale nothing
~d char-numeric? day of month date-day
~e any day of month, blank padded date-day
~f char-decimal? seconds+fractional seconds, using locale's decimal separator (e.g. 5.2). date-second+date-nanosecond
~h char-alphabetic? same as ~b nothing
~H char-numeric? hour date-hour
~k any hour, blank padded date-hour
~m char-numeric? month date-month
~M char-numeric? minute date-minute
~S char-numeric? second date-second
~y any 2-digit year date-year within 50 years
~Y char-signed-numeric? 4-digit year date-year
~z any time zone date-zone-offset

Date/Time Literals (*)

Literal Date/Time forms.

Usage

(import srfi-19-literals)
date-literal-form
[parameter] (date-literal-form [FORM]) -> (or boolean symbol)

The date literal format.

#f
#<srfi-19#date ...>
SRFI-10
#,(srfi-19-date ...)
#t
#@... ; the default
|#@|
#@...
time-literal-form
[parameter] (time-literal-form [FORM]) -> (or boolean symbol)

The time literal format.

#f
#<srfi-19#time ...>
SRFI-10
#,(srfi-19-time ...) ; the default
#t ##...
|##|
##...

Use the ## form at your peril.

read-date-literal
[procedure] (read-date-literal [PORT]) -> list

Read a date-literal from the PORT, in one of the supported forms, and return the object creation source form; '(make-date ....).

PORT
input-port ; default (current-input-port)

Supported forms:

"~Y-~m-~dT~H:~M:~f~z"
date time timezone
"~Y-~m-~dT~H:~M:~f"
date time
"~Y-~m-~d"
date
"~H:~M:~f~z"
time timezone; date components from (current-date)
"~H:~M:~f"
time; date components from (current-date)
write-date-literal
[procedure] (write-date-literal DATE [PORT])

Write the DATE to the PORT using a string ISO form; "~Y-~m-~dT~H:~M:~f~z".

PORT
output-port ; default (current-output-port)

Time Period (*)

A time-period is an interval, [begin end), where begin and end are time objects of the same clock type.

Usage

(import srfi-19-period)
make-time-period
[procedure] (make-time-period BEGIN END [CLOCK-TYPE (default-date-clock-type)]) -> time-period

Returns a new time-period object. The clock types must be compatible.

BEGIN maybe a seconds value, a date, or a time (except time-duration). A seconds value or date are converted to CLOCK-TYPE.

END maybe a seconds value, a date, or a time. A seconds value or date are converted to the same clock type as BEGIN. A time-duration is treated as an offset from BEGIN.

time-period-copy
[procedure] (time-period-copy TIME-PERIOD) -> time-period

Returns a copy of TIME-PERIOD.

time-period-begin
[procedure] (time-period-begin TIME-PERIOD)

Returns the start time for the TIME-PERIOD.

time-period-end
[procedure] (time-period-end TIME-PERIOD) -> time

Returns the end time for the TIME-PERIOD.

time-period-last
[procedure] (time-period-last TIME-PERIOD) -> time

Returns the last time for the TIME-PERIOD; (time-period-end - TIME-FINE-GRAIN).

time-period-type
[procedure] (time-period-type TIME-PERIOD) -> symbol

Returns the clock-type of the TIME-PERIOD.

time-period?
[procedure] (time-period? OBJECT) -> boolean

Is OBJECT a time-period?

time-period-duration
[procedure] (time-period-duration TIME-PERIOD) -> time

Returns the time-duration of the TIME-PERIOD.

time-period-hash
[procedure] (time-period-hash TIME-PERIOD [BOUND]) -> fixnum

Hash value for TIME-PERIOD within BOUND.

time-period-compare
[procedure] (time-period-compare TIME-PERIOD-1 TIME-PERIOD-2) -> integer

Returns -1, 0, or +1.

time-period=?
[procedure] (time-period=? TIME-PERIOD-1 TIME-PERIOD-2) -> boolean

Does TIME-PERIOD-1 begin & end with TIME-PERIOD-2?

time-period<?
[procedure] (time-period<? TIME-PERIOD-1 TIME-PERIOD-2) -> boolean

Does TIME-PERIOD-1 end before TIME-PERIOD-2 begins?

time-period>?
[procedure] (time-period>? TIME-PERIOD-1 TIME-PERIOD-2) -> boolean

Does TIME-PERIOD-1 begin after TIME-PERIOD-2 ends?

time-period<=?
[procedure] (time-period<=? TIME-PERIOD-1 TIME-PERIOD-2) -> boolean

Does TIME-PERIOD-1 end on or before TIME-PERIOD-2 begins?

time-period>=?
[procedure] (time-period>=? TIME-PERIOD-1 TIME-PERIOD-2) -> boolean

Does TIME-PERIOD-1 begin on or after TIME-PERIOD-2 ends?

time-period-preceding
[procedure] (time-period-preceding TIME-PERIOD-1 TIME-PERIOD-2) -> (or false time-period)

Return the portion of TIME-PERIOD-1 before TIME-PERIOD-2 or #f when it doesn't precede.

time-period-succeeding
[procedure] (time-period-succeeding TIME-PERIOD-1 TIME-PERIOD-2) -> (or false time-period)

Return the portion of TIME-PERIOD-1 after TIME-PERIOD-2 or #f when it doesn't succeed.

time-period-contains/period?
[procedure] (time-period-contains/period? TIME-PERIOD-1 TIME-PERIOD-2) -> boolean

Is TIME-PERIOD-2 within TIME-PERIOD-1?

time-period-contains/time?
[procedure] (time-period-contains/time? TIME-PERIOD TIME) -> boolean

Is TIME within TIME-PERIOD?

TIME is converted to a compatible clock-type if possible.

time-period-contains/date?
[procedure] (time-period-contains/date? TIME-PERIOD DATE) -> boolean

Is DATE within TIME-PERIOD?

DATE is converted to a compatible time if possible.

time-period-contains?
[procedure] (time-period-contains? TIME-PERIOD OBJECT) -> boolean

Is OBJECT within TIME-PERIOD?

OBJECT maybe a time, date, or time-period.

time-period-intersects?
[procedure] (time-period-intersects? TIME-PERIOD-1 TIME-PERIOD-2) -> boolean

Does TIME-PERIOD-2 overlap TIME-PERIOD-1?

time-period-intersection
[procedure] (time-period-intersection TIME-PERIOD-1 TIME-PERIOD-2) -> (or false time-period)

The overlapping time-period of TIME-PERIOD-2 and TIME-PERIOD-1, or #f when no overlap.

time-period-union
[procedure] (time-period-union TIME-PERIOD-1 TIME-PERIOD-2) -> (or false time-period)

Returns the time-period spanned by TIME-PERIOD-1 and TIME-PERIOD-2, or #f when they do not intersect.

time-period-span
[procedure] (time-period-span TIME-PERIOD-1 TIME-PERIOD-2) -> time-period

Returns the time-period spanned by TIME-PERIOD-1 and TIME-PERIOD-2, including any gaps.

time-period-shift
[procedure] (time-period-shift TIME-PERIOD DURATION) -> time-period

Returns a copy of TIME-PERIOD shifted by DURATION.

time-period-shift!
[procedure] (time-period-shift! TIME-PERIOD DURATION) -> time-period

Returns TIME-PERIOD shifted by DURATION.

SRFI 29 bundles

en
English (American) - only shipping u support at the moment
de
German
it
Italian
es
Spanish
nl
Dutch
pt_br
Brazilian Portuguese

Default bundle is en.

Examples

;must be done before 1st invocation of a srfi-19 export
(import locale)
(set-locale-category! 'timezone
  (posix-timezone-string->timezone-components
    ;some acceptable posix tz form
    "XSX+2:00XDX+1:00:00"
    ;source of tz info
    '("POSIX" "TZ")))

(current-timezone-components)
;=> ((tag . timezone) (name . "XSX+2:00XDX+1:00:00") (source "POSIX" "TZ")
;=> (std-name . "XSX") (std-offset . 7200) (dst-name . "XDX") (dst-offset . 3600)
;=> (dst? . #t))

;now we can use srfi-19 in our runtime tz
(import (chicken format))
(import srfi-19)
(format #t "Present Day: ~A~%Present Time: ~A~%: Hah, hah, hah.~%"
  (current-date) (current-time))
(import (only (srfi 128) make-comparator))

(define (make-date-comparator)
  (import (only srfi-19-date date? date=? date<? date-hash))
  (make-comparator date? date=? date<? date-hash) )

(define (make-time-comparator)
  (import (only srfi-19-time time? time=? time<? time-hash))
  (make-comparator time? time=? time<? time-hash) )

(define (make-time-period-comparator)
  (import (only srfi-19-period time-period? time-period=? time-period<? time-period-hash))
  (make-comparator srfi-19-period time-period? time-period=? time-period<? time-period-hash) )

Notes

Bugs and Limitations

If you are adding hours, minutes, seconds, or milliseconds, the assumption is that you want precision to the hour, and will result in a different hour.

var m = moment(new Date(2011, 2, 12, 5, 0, 0)); // the day before DST in the US
m.hours(); // 5
m.add(24, 'hours').hours(); // 6

but this implementation says 1 day = 24 hours, so same hour.

Requirements

utf8 srfi-1 srfi-18 srfi-29 miscmacros locale record-variants check-errors

Test test-utils format

Author

Kon Lovett

Repository

This egg is hosted on the CHICKEN Subversion repository:

https://anonymous@code.call-cc.org/svn/chicken-eggs/release/5/srfi-19

If you want to check out the source code repository of this egg and you are not familiar with Subversion, see this page.

Acknowledgments

Version history

4.10.2
Fix seconds->date optional timezone-info.
4.10.1
Fix signatures (again).
4.10.0
Extend <time-type>-time functions. Fix signatures.
4.9.11
Remove useless signatures (bug reported by shawnw on #chicken irc).
4.9.10
Add make-time*, deprecate make-duration, fix signatures.
4.9.9
Read BCE (full) years (~Y).
4.9.8
Fix parameters error on bad argument.
4.9.7
Add ~f input conversion. Fix time-period-compare.
4.9.6
Register the feature. Add leap-day?.
4.9.5
Remove code/data duplicates.
4.9.4
Restore copy-time & add copy-date.
4.9.3
Fix *-hash range test.
4.9.2
Fix time-hash result bounds.
4.9.1
Fix date-adjust synonym lookup.
4.9.0
SRFI-69 conforming date-hash, time-hash, & period-hash. Drop srfi-69 dependency.
4.8.2
Fix ~V.
4.8.1
Better date/time-hash. Fix time-compare negative seconds. nanoseconds->time, milliseconds->time, seconds->time, & date->seconds have optional. time-abs & time-negate affect time-second only.
4.8.0
Add Chibi time routines. Fix seconds->time & time->seconds negative seconds.
4.7.5
Add default locale bundle.
4.7.4
Add C locale bundle.
4.7.3
make-date accepts year 0.
4.7.2
date-adjust* accepts symbols.
4.7.1
Fix date<?/date>? swapped bug; reported on #irc by gahr, Jan 26 '23
4.7.0
Add Chibi ~g & ~u output conversion specifiers.
4.6.0
Add date-adjust*.
4.5.2
Better time-literal-form default.
4.5.1
Fix SRFI-69 compatible time-hash, date-hash, time-period-hash.
4.5.0
Add SRFI-69/128 compatible time-hash, date-hash, time-period-hash.
4.4.10
Indicate pure procedures. Fix time conversion procedure signatures.
4.4.9
Add strong typing.
4.4.8
Fix time-copy, add time-copy/date-copy, deprecate copy-date && copy-time, add time-period interval relations.
4.4.7
.
4.4.6
Fix time-utc->date default TZ.
4.4.0
Add Date/Time source literals via the srfi-19-literals module.
4.3.2
Allow partial (time only) date read.
4.3.1
.
4.3.0
Deprecate 'srfi-10 record print form. Fix record printing.
4.3.0
nanoseconds->seconds, milliseconds->seconds, & date->seconds do not necessarily return an inexact.
4.2.1
.
4.2.0
Fix make-date w/o tz.
4.1.2
.
4.1.1
Fix seconds->date flonum argument handling.
4.1.0
Variants.
4.0.2
Add dependencies.
4.0.1
Add dependencies.
4.0.0
C5 port.

License

Copyright (C) 2009-2024 Kon Lovett. All rights reserved.

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 shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ASIS, 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.

Copyright (C) I/NET, Inc. (2000, 2002, 2003). All Rights Reserved. Copyright (C) Neodesic Corporation (2000). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Scheme Request For Implementation process or editors, except as needed for the purpose of developing SRFIs in which case the procedures for copyrights defined in the SRFI process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the authors or their successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.