For more information including compatibility, examples and test cases, see https://github.com/petercrlane/r7rs-libs

(The documentation for the slib time packages is combined in the following, as the libraries are interconnected.)

0.1. Time/Date

The R7RS standard has a library (scheme time) which contains three functions: current-second, to obtain the current time in seconds since 1/1/1970; current-jiffy, which returns an implementation-defined fraction of a second from an implementation-specific start point; and jiffies-per-second, which returns the implementation-specific number of "jiffies" per second. The libraries provided in SLIB help convert to and from larger units of time (such as days and years), and also take account of time-zones. SRFI 19 provides a useful standard library for working with dates and times, where available.

SLIB provides a small set of libraries for managing times, dates and time-zones. These reflect Lisp and Posix treatments of time. The libraries use a variety of data formats:

Calendar Time

number of seconds since 1st January 1970 (as used by R7RS current-second)

Decoded Time

nine values for second, minute, hour, date, month, year, day-of-week, daylight-saving-time? and time-zone. Note that months start with January = 1, days of week start with Monday = 0

TM Time

(C’s struct tm) nine values for seconds, minutes, hours, date, month, year, day-of-week, days-in-year, daylight-saving-time?. Note that months start with January = 0, years start with 1900 = 0, days of week start with Sunday = 0

Universal Time

number of seconds since 1st January 1900

The libraries themselves are:

  • (slib common-lisp-time): From Lisp, using Decoded Time and Universal Time.

  • (slib posix-time): From C/Posix, using TM Time and Calendar Time.

  • (slib time-core): main time conversion functions

  • (slib time-zone): computes time-zones and daylight-saving times from the time-zone environment variable or files

  • (slib tzfile): reads from a time-zone file

Time zone information is ultimately read via tzfile which looks for either the environment variable "TZ" or in one of a specified set of paths. (This currently does not appear to support Windows.)

None of these libraries handles leap seconds.

0.1.1. (slib common-lisp-time)

These functions are based on those in Common Lisp to convert between Decoded Time and Universal Time.

get-decoded-time returns the current time in Decoded Time format, as nine values. (get-decoded-time) is short for (decode-universal-time (get-universal-time)).

> (get-decoded-time)
((values) 58 15 18 18 4 2017 1 #f 0)

get-universal-time returns the current time of day as a single integer in Universal Time format representing the number of seconds since 1/1/1900: note for comparison how R7RS’s (current-second) returns a much smaller value (Calendar Time, the number of seconds since 1/1/1970).

> (get-universal-time)
3701527370.61162
> (current-second)
1492540922.30859

decode-universal-time converts a universal time (with an optional time-zone) into the nine values of Decoded Time format.

> (decode-universal-time (get-universal-time))
((values) 41 2 18 18 4 2017 1 #f 0)

The optional time-zone is the number of hours away from GMT. This is backwards from what you might expect: British Summer Time, one hour ahead of GMT, is given by -1.

> (decode-universal-time (get-universal-time) -1)   ; current time in London (BST = GMT+1)
((values) 26 4 19 18 4 2017 1 #f -1)
> (decode-universal-time (get-universal-time) -5.5) ; current time in New Delhi (GMT+5.5)
((values) 54 35 23 18 4 2017 1 #f -11/2)

encode-universal-time takes the first six values of Decoded Time format, and returns a Universal Time representation.

> (encode-universal-time 8 50 21 18 3 2017)
3698862608.0

0.1.2. (slib time-core)

A collection of functions to help in time conversions based around TM Time.

current-time is the same as current-second. This is the Calendar Time, defined relative to 1/1/1970.

> (current-time)
1492540922.30859

difftime subtracts two times, given as seconds.

leap-year? returns true if given year is a leap-year, false otherwise.

> (leap-year? 2000)
#t
> (leap-year? 2004)
#t
> (leap-year? 1900)
#f

offset-time adds two times together, given as seconds.

time:gmtime takes a time in seconds and returns the TM Time information, assuming the location is GMT:

> (time:gmtime (current-time))
#(39 45 18 18 3 117 2 107 0 0 "GMT")            ; <1>
  1. time is 18:45 39s, 18 is the date, month is April (3), year is 2017 (117+1900), day of week is Tuesday (2), 108 days from 1st January. The last 0 is for the offset due to the time zone.

Note that time:gmtime calls time:split: (time:gmtime tm) = (time:split tm 0 0 "GMT")

0.1.3. (slib posix-time)

This library provides data structures and functions similar to those in C’s "time.h".

asctime converts a TM time into a string representation:

> (asctime (gmtime (current-time)))
"Tue Apr 18 20:18:15 2017\n"

gmtime takes a Calendar time (in seconds) and returns the TM Time information, assuming the location is GMT (the same as time:gmtime).

gtime is short for (asctime (gmtime ..))

> (gtime (current-time))
"Tue Apr 18 20:38:28 2017\n"

localtime converts a Calendar time into a TM Time. An optional second argument specifies the time zone.

> (localtime (current-time) (read-tzfile "Asia/Calcutta"))
#(51 16 2 19 3 117 3 108 0 -19800 #(73 83 84))
> (localtime (current-time))
#(8 47 21 18 3 117 2 107 1 -3600 #(66 83 84))

ctime is short for (asctime (localtime …))

> (ctime (current-time))
"Tue Apr 18 21:44:32 2017\n"
> (ctime (current-time) (read-tzfile "Asia/Calcutta"))
"Wed Apr 19 02:16:20 2017\n"

mktime converts the TM Time to Calendar time:

> (current-time)
1492548597.89966
> (localtime (current-time))
#(8 50 21 18 3 117 2 107 1 -3600 #(66 83 84))
> (mktime (localtime (current-time)))
1492552289.0

gmktime is the same as mktime, except it assumes a GMT time zone.

0.1.4. (slib time-zone)

read-tzfile takes a path or, if given #f, uses a known path to a time-zone file. The function then calls tzfile:read from (slib tzfile) and returns the result (see below).

read-tzfile is used by time-zone to read the specific time-zone information for a given locality:

> (read-tzfile "Asia/Dili")
#(tz:file "/usr/share/zoneinfo/Asia/Dili" #(#(#(76 77 84) 30140 #f #f #f) #(#(84 76 84) 28800 #f #f #f) #(#(74 83 84) 32400 #f #f #f) #(#(84 76 84) 32400 #f #f #f) #(#(87 73 84 65) 28800 #f #f #f) #(#(84 76 84) 32400 #f #f #f)) #() #(-2147483648 -1830414140 -879152400 -766054800 199897200 969120000) #(0 1 2 3 4 3))
> (read-tzfile "GMT")
#(tz:file "/usr/share/zoneinfo/GMT" #(#(#(71 77 84) 0 #f #f #f)) #() #() #())

time-zone will either:

  • return its argument, if it is a vector (i.e. already a time-zone description)

  • use read-tzfile if the argument is #f or a time-zone file name prefixed with ":"

  • use string→time-zone if the argument is a string without ":" at start

  • return #f if it could not read the time-zone

> (time-zone #(tz:file "/usr/share/zoneinfo/GMT" #(#(#(71 77 84) 0 #f #f #f)) #() #() #()))
#(tz:file "/usr/share/zoneinfo/GMT" #(#(#(71 77 84) 0 #f #f #f)) #() #() #())
> (time-zone ":Asia/Dili")
#(tz:file "/usr/share/zoneinfo/Asia/Dili" #(#(#(76 77 84) 30140 #f #f #f) #(#(84 76 84) 28800 #f #f #f) #(#(74 83 84) 32400 #f #f #f) #(#(84 76 84) 32400 #f #f #f) #(#(87 73 84 65) 28800 #f #f #f) #(#(84 76 84) 32400 #f #f #f)) #() #(-2147483648 -1830414140 -879152400 -766054800 199897200 969120000) #(0 1 2 3 4 3))
> (time-zone "CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00")
#(tz:rule "CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00" "CST" "CDT" 21600 18000 (3 2 0 7200) (11 1 0 7200))

0.1.5. (slib tzfile)

There is only one exported function: tzfile:read. This function reads time-zone information from a system-specified file. For example, on Linux, the file may be "/etc/localtime":

> (import (slib tzfile))
> (tzfile:read "/etc/localtime")
("/etc/localtime" #(#(#(76 77 84) -75 #f #f #f) #(#(66 83 84) 3600 #t #t #f)
#(#(71 77 84) 0 #f #t #f) #(#(66 68 83 84) 7200 #t #t #f) #(#(66 83 84) 3600 #f
#f #f) #(#(66 83 84) 3600 #t #t #t) #(#(71 77 84) 0 #f #t #t) #(#(71 77 84) 0
#f #f #f)) #() #(-2147483648 -1691964000 -1680472800 -1664143200 -1650146400
-1633903200 -1617487200 -1601848800 -1586037600 -1570399200 -1552168800
-1538344800 -1522533600 -1507500000 -1490565600 -1473631200 -1460930400
-1442786400 -1428876000 -1410732000 -1396216800 -1379282400 -1364767200
-1348437600 -1333317600 -1315778400 -1301263200 -1284328800 -1269813600
-1253484000 -1238364000 -1221429600 -1206914400 -1189980000 -1175464800
-1159135200 -1143410400 -1126476000 -1111960800 -1095631200 -1080511200
-1063576800 -1049061600 -1032127200 -1017612000 -1001282400 -986162400
-969228000 -950479200 -942012000 -904518000 -896050800 -875487600 -864601200
-844038000 -832546800 -812588400 -798073200 -781052400 -772066800 -764805600
-748476000 -733356000 -719445600 -717030000 -706748400 -699487200 -687996000
-668037600 -654732000 -636588000 -622072800 -605743200 -590623200 -574293600
-558568800 -542239200 -527119200 -512604000 -496274400 -481154400 -464220000
-449704800 -432165600 -417650400 -401320800 -386200800 -369266400 -354751200
-337816800 -323301600 -306972000 -291852000 -276732000 -257983200 -245282400
-226533600 -213228000 -195084000 -182383200 -163634400 -150933600 -132184800
-119484000 -100735200 -88034400 -68680800 -59004000 -37242000 57722400 69818400
89172000 101268000 120621600 132717600 152071200 164167200 183520800 196221600
214970400 227671200 246420000 259120800 278474400 290570400 309924000 322020000
341373600 354675600 372819600 386125200 404269200 417574800 435718800 449024400
467773200 481078800 499222800 512528400 530672400 543978000 562122000 575427600
593571600 606877200 625626000 638326800 657075600 670381200 688525200 701830800
719974800 733280400 751424400 764730000 782874000 796179600 814323600 820454400
828234000 846378000 859683600 877827600 891133200 909277200 922582800 941331600
954032400 972781200 985482000 1004230800 1017536400 1035680400 1048986000
1067130000 1080435600 1099184400 1111885200 1130634000 1143334800 1162083600
1174784400 1193533200 1206838800 1224982800 1238288400 1256432400 1269738000
1288486800 1301187600 1319936400 1332637200 1351386000 1364691600 1382835600
1396141200 1414285200 1427590800 1445734800 1459040400 1477789200 1490490000
1509238800 1521939600 1540688400 1553994000 1572138000 1585443600 1603587600
1616893200 1635642000 1648342800 1667091600 1679792400 1698541200 1711846800
1729990800 1743296400 1761440400 1774746000 1792890000 1806195600 1824944400
1837645200 1856394000 1869094800 1887843600 1901149200 1919293200 1932598800
1950742800 1964048400 1982797200 1995498000 2014246800 2026947600 2045696400
2058397200 2077146000 2090451600 2108595600 2121901200 2140045200) #(2 1 2 1 2
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 3 1 3 1 3 1 3 1 3 1 2 1 2 1 3 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 4 6 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1
2 1 2 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 7 5 6 5 6 5 6
5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6
5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6))