# (lispkit date-time)

Library `(lispkit date-time)` provides functionality for handling time zones, dates, and times. Time zones are represented by string identifiers referring to the region and corresponding city, e.g. `"America/Los_Angeles"`. Dates and times are represented via `date-time` data structures. These encapsulate the following components:

* *time zone*: the time zone of the date
* *date*: the date consisting of its year, month, and day
* *time*: the time on *date* consisting of the hour (>= 0, < 24), the minute (>= 0, < 60), the second (>= 60, <60), and the nano second.

The library uses a floating-point representation of seconds since 00:00 UTC on January 1, 1970, as a means to refer to specific points in time independent of timezones. This means that, for instance, for comparing date-times with each other, a user would have to convert them to seconds and then compare the seconds instead. Here is an example:

```scheme
(define initial-time (date-time "Europe/Zurich"))
(define later-time (date-time "GMT"))
(date-time< initial-time later-time)
  ⇒  #t
; the following line is equivalent:
(< (date-time->seconds initial-time) (date-time->seconds later-time))
  ⇒  #t
```

For now, `(lispkit date-time)` assumes all dates are based on the Gregorian calendar, independent of the settings at the operating system-level.

## Time zones

Time zones are represented by string identifiers referring to the region and corresponding city, e.g. `"America/Los_Angeles"`. Procedure `timezones` returns a list of all supported time zone identifiers. Each time zone has a locale-specific name and an offset in seconds from Greenwhich Mean Time. Some time zones also have an abbreviation which can be used as an alternative way to identify a time zone.

**(timezones)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(timezones&#x20;*****filter*****)**

Returns a list of string identifiers for all supported time zones. If *filter* is provided, it can either be set to `#f`, in which case a list of abbreviations is returned instead, or it is a string, and only time zone identifiers which contain *filter* are returned.

```scheme
(timezones #f)
⇒  ("CEST" "GST" "NZDT" "BRST" "WEST" "AST" "MSD" "CDT" "WIT" "MSK" "COT" "IST" "EST" "BST" "CLST" "NDT" "TRT" "EET" "IRST" "EDT" "BRT" "ICT" "CST" "AKST" "BDT" "PHT" "SGT" "WET" "ART" "CLT" "CAT" "UTC" "EEST" "ADT" "JST" "HST" "PET" "MST" "NST" "NZST" "GMT" "MDT" "PKT" "WAT" "HKT" "AKDT" "KST" "PST" "CET" "PDT" "EAT")
```

**(timezone?&#x20;*****obj*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if *obj* is a valid time zone identifier or time zone abbreviation; returns `#f` otherwise.

**(timezone)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(timezone&#x20;*****ident*****)**

Returns the identifier for the time zone specified by *ident*. *ident* can either be an identifier, an abbreviation or a GMT offset as a floating-point number or integer. If *ident* does not refer to a supported time zone, procedure `timezone` will fail.

**(timezone-name&#x20;*****tz*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(timezone-name&#x20;*****tz locale*****)**\
\&#xNAN;**(timezone-name&#x20;*****tz locale format*****)**

Returns a locale-specific name for time zone *tz*. If *locale* is not specified, the current locale defined at the operating-system level is used. *format* specifies the name format. It can have one of the following symbolic values:

* `standard`
* `standard-short`
* `dst`
* `dst-short`
* `generic`
* `generic-short`

**(timezone-abbreviation&#x20;*****tz*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a string representing a time zone abbreviation for *tz*; e.g. `"PDT"`. If the time zone *tz* does not have an abbreviation, this function returns `#f`.

**(timezone-gmt-offset&#x20;*****tz*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the difference in seconds between time zone *tz* and Greenwich Mean Time. The difference is returned as a floating-point number (since seconds are always represented as such by this library).

## Time stamps

Time stamps, i.e. discreet points in time, are represented as floating-point numbers corresponding to the number of seconds since 00:00 UTC on January 1, 1970.

**(current-seconds)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a floating-point number representing the number of seconds since 00:00 UTC on January 1, 1970.

**(seconds->date-time&#x20;*****secs*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(seconds->date-time&#x20;*****secs tz*****)**

Converts the given number of seconds *secs* into date-time format for the given time zone *tz*. *secs* is a floating-point number. It is interpreted as the number of seconds since 00:00 UTC on January 1, 1970. *secs* is negative if the date-time is earlier than 00:00 UTC on January 1, 1970. If *tz* is missing, the current, operating-system defined time zone is used.

**(date-time->seconds&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a floating-point number representing the number of seconds since 00:00 UTC on January 1, 1970 for the given date-time object *dtime*.

## Date-times

**date-time-type-tag** <img src="/files/lodKVmz8JxFoYYJUdrx6" alt="" data-size="line">

Symbol representing the `date-time` type. The `type-for` procedure of library `(lispkit type)` returns this symbol for all date/time objects.

**(date-time?&#x20;*****obj*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if *obj* is a date-time object; returns `#f` otherwise.

**(date-time)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(date-time&#x20;*****year month day*****)**\
\&#xNAN;**(date-time&#x20;*****year month day hour*****)**\
\&#xNAN;**(date-time&#x20;*****year month day hour min*****)**\
\&#xNAN;**(date-time&#x20;*****year month day hour min sec*****)**\
\&#xNAN;**(date-time&#x20;*****year month day hour min sec nano*****)**\
\&#xNAN;**(date-time&#x20;*****tz*****)**\
\&#xNAN;**(date-time&#x20;*****tz year month day*****)**\
\&#xNAN;**(date-time&#x20;*****tz year month day hour*****)**\
\&#xNAN;**(date-time&#x20;*****tz year month day hour min*****)**\
\&#xNAN;**(date-time&#x20;*****tz year month day hour min sec*****)**\
\&#xNAN;**(date-time&#x20;*****tz year month day hour min sec nano*****)**

Constructs a date-time representation out of the given date time components. *tz* is the only string argument; it is referring to a time zone. All other arguments are numeric arguments. This procedure returns a date-time object for the specified time at the given date. If no date components are provided as arguments, procedure `date-time` returns a date-time for the current date and time.

**(week->date-time&#x20;*****year week*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(week->date-time&#x20;*****year week wday*****)**\
\&#xNAN;**(week->date-time&#x20;*****year week wday hour*****)**\
\&#xNAN;**(week->date-time&#x20;*****year week wday hour min*****)**\
\&#xNAN;**(week->date-time&#x20;*****year week wday hour min sec*****)**\
\&#xNAN;**(week->date-time&#x20;*****year week wday hour min sec nano*****)**\
\&#xNAN;**(week->date-time&#x20;*****tz year week*****)** **(week->date-time&#x20;*****tz year week wday*****)**\
\&#xNAN;**(week->date-time&#x20;*****tz year week wday hour*****)**\
\&#xNAN;**(week->date-time&#x20;*****tz year week wday hour min*****)**\
\&#xNAN;**(week->date-time&#x20;*****tz year week wday hour min sec*****)**\
\&#xNAN;**(week->date-time&#x20;*****tz year week wday hour min sec nano*****)**

Constructs a date-time representation out of the given date time components. *tz* is the only string argument; it is referring to a time zone. All other arguments are numeric arguments. Argument *wday* specifies the week day in the given week. Week days are given numbers from 1 (= Monday) to 7 (= Sunday). This procedure returns a date-time object for the specified time at the given date.

The difference to `date-time` is that this procedure does not refer to a month and day. It rather refers to the week number as well as the weekday within this specified week number.

**(date-time-in-timezone&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(date-time-in-timezone&#x20;*****dtime tzone*****)**

Constructs a date-time representation of the same point in time like *dtime*, but in a potentially different time zone *tzone*. If *tzone* is not given, the default time zone specified by the user in the operating system will be used.

**(string->date-time&#x20;*****str*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(string->date-time&#x20;*****str tz*****)**\
\&#xNAN;**(string->date-time&#x20;*****str tz locale*****)**\
\&#xNAN;**(string->date-time&#x20;*****str tz locale format*****)**

Extracts a date and time from the given string *str* in the time zone *tz*, or the current time zone if *tz* is omitted. The format of the string representation is defined in terms of *locale* and *format*. If both *locale* and *format* are omitted or set to `#f`, `string->date-time` assumes the date and time is in ISO 8601 format with UTC as timezone. *format* can have three different forms:

1. Combined format identifier for date and time: `date-time` parsing is based on the settings of the underlying operating system. *format* is one of the following symbols: `none`, `short`, `medium`, `long`, or `full`.
2. Separate format identifiers for date and time: `date-time` parsing is based on the settings of the operating system, but the format for dates and times is specified separately. *format* is a list of the form `(`*dateformat* *timeformat*`)` where both *dateformat* and *timeformat* are one of the 5 symbols listed under 1. This makes it possible, for instance, to just parse a date (without time) in string form to a date-time object, e.g. by using `(short none)` as *format*.
3. Custom format specifier: `date-time` parsing is based on a custom format string. *format* is a string using the following characters as placeholders. Repetitions of the placeholder characters are used to specify the width and format of the field.
   * `y`: Year
   * `M`: Month
   * `d`: Day
   * `H`: Hour (12 hours)
   * `h`: Hour (24 hours)
   * `m`: Minute
   * `s`: Second
   * `S`: Micro second
   * `Z`: Time zone
   * `a`: AM/PM
   * `E`: Weekday

Here are a few examples:

```
EEEE, MMM d, yyyy       →  Thursday, Feb 8, 1973
dd/MM/yyyy              →  08/02/1973
dd-MM-yyyy HH:mm        →  08-02-1973 17:01
MMM d, h:mm a           →  Thu 8, 2:11 AM
yyyy-MM-dd'T'HH:mm:ssZ  →  1973-08-02T17:01:31+0000
HH:mm:ss.SSS            →  11:02:19.213
```

**(date-time->string&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(date-time->string&#x20;*****dtime locale*****)**\
\&#xNAN;**(date-time->string&#x20;*****dtime locale format*****)**

Returns a string representation of the date-time object *dtime*. The format of the string is defined in terms of *locale* and *format*. *format* can have three different forms (just like for `string->date-time`):

1. Combined format identifier for date and time: `date-time` formatting is based on the settings of the operating system. *format* is one of the following symbols: `none`, `short`, `medium`, `long`, or `full`.
2. Separate format identifiers for date and time: `date-time` formatting is based on the settings of the operating system, but the format for dates and times is specified separately. *format* is a list of the form `(`*dateformat* *timeformat*`)` where both *dateformat* and *timeformat* are one of the 5 symbols listed under 1. This makes it possible, for instance, to just output a date (without time) in string form, e.g. by using `(short none)` as *format*.
3. Custom format specifier: `date-time` formatting is based on a custom format string. *format* is a string using the following characters as placeholders. Repetitions of the placeholder characters are used to specify the width and format of the field.
   * `y`: Year
   * `M`: Month
   * `d`: Day
   * `H`: Hour (12 hours)
   * `h`: Hour (24 hours)
   * `m`: Minute
   * `s`: Second
   * `S`: Micro second
   * `Z`: Time zone
   * `a`: AM/PM
   * `E`: Weekday

Here are a few examples:

```
EEEE, MMM d, yyyy       →  Thursday, Feb 8, 1973
dd/MM/yyyy              →  08/02/1973
dd-MM-yyyy HH:mm        →  08-02-1973 17:01
MMM d, h:mm a           →  Thu 8, 2:11 AM
yyyy-MM-dd'T'HH:mm:ssZ  →  1973-08-02T17:01:31+0000
HH:mm:ss.SSS            →  11:02:19.213
```

**(date-time->iso8601-string&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(date-time->iso8601-string&#x20;*****dtime fract*****)**\
\&#xNAN;**(date-time->iso8601-string&#x20;*****dtime fract? excl-tz*****)**

Returns a string representation of the date-time object *dtime* in ISO 8601 format. If *fract?* is set to true, seconds are output as floating-point numbers, i.e. with fractional values (default is `#f`). If *excl-tz?* is set to true, no timezone designator is included in the output (default is `#f`).

**(date-time-timezone&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the time zone of *dtime*.

**(date-time-year&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the year of *dtime*.

**(date-time-month&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the month of *dtime*.

**(date-time-day&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the day of *dtime*.

**(date-time-hour&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the hour of *dtime*.

**(date-time-minute&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the minute of *dtime*.

**(date-time-second&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the second of *dtime*.

**(date-time-nano&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the nano-second of *dtime*.

**(date-time-weekday&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the week day of *dtime*. Week days are represented as fixnums where 1 is Monday, 2 is Tuesday, ..., and 7 is Sunday.

**(date-time-week&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the week number of *dtime* according to the ISO-8601 standard. Based on this standard, weeks start on Monday. The first week of the year is the week that contains that year's first Thursday.

**(date-time-dst-offset&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the daylight saving time offset of *dtime* in seconds related to GMT. If daylight savings time is not active, `date-time-dst-offset` returns `0.0`. The result is always a floating-point number.

**(date-time-hash&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a hash code for the given date-time object. This hash code can be used in combination with both `date-time=?` and `date-time-same?`.

## Date-time predicates

**(date-time-same?&#x20;*****dtime1 dtime2*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if date-time *dtime1* and *dtime2* have the same timezone and refer to the same point in time, i.e. `(date-time->seconds dtime1)` and `(date-time->seconds dtime2)` are equals.

```scheme
(define d1 (date-time 'CET))
(define d2 (date-time-in-timezone d1 'PST))
(date-time-same? d1 d1)  ⇒  #t
(date-time-same? d1 d2)  ⇒  #f
(date-time=? d1 d2)      ⇒  #t
```

**(date-time=?&#x20;*****dtime1 dtime2*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if date-time *dtime1* and *dtime2* specify the same point in time, i.e. `(date-time->seconds dtime1)` and `(date-time->seconds dtime2)` are equals.

```scheme
(define d1 (date-time 'CET))
(define d2 (date-time-in-timezone d1 'PST))
(date-time=? d1 d2)                ⇒  #t
(date-time=? d1 (date-time 'CET))  ⇒  #f
```

**(date-time\<?&#x20;*****dtime1 dtime2*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if date-time *dtime1* specifies an earlier point in time compared to *dtime2*, i.e. `(date-time->seconds dtime1)` is less than `(date-time->seconds dtime2)`.

**(date-time>?&#x20;*****dtime1 dtime2*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if date-time *dtime1* specifies a later point in time compared to *dtime2*, i.e. `(date-time->seconds dtime1)` is greater than `(date-time->seconds dtime2)`.

**(date-time<=?&#x20;*****dtime1 dtime2*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if date-time *dtime1* specifies an earlier or equal point in time compared to *dtime2*, i.e. `(date-time->seconds dtime1)` is less than or equal to `(date-time->seconds dtime2)`.

**(date-time>=?&#x20;*****dtime1 dtime2*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if date-time *dtime1* specifies a later or equal point in time compared to *dtime2*, i.e. `(date-time->seconds dtime1)` is greater than or equal to `(date-time->seconds dtime2)`.

**(date-time-has-dst?&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if daylight saving time is active for *dtime*; returns `#f` otherwise.

## Date-time operations

**(date-time-add&#x20;*****dtime days*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(date-time-add&#x20;*****dtime days hrs*****)**\
\&#xNAN;**(date-time-add&#x20;*****dtime days hrs min*****)**\
\&#xNAN;**(date-time-add&#x20;*****dtime days hrs min sec*****)**\
\&#xNAN;**(date-time-add&#x20;*****dtime days hrs min sec nano*****)**

Compute a new date-time from adding *days*, *hrs*, *min*, *sec*, and *nano* (all fixnums) to the given date-time *dtime*. The resulting date-time is using the same timezone like *dtime*.

**(date-time-add-seconds&#x20;*****dtime sec*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Compute a new date-time from adding the number of seconds *sec* (a flonum) to the given date-time *dtime*.

**(date-time-diff-seconds&#x20;*****dtime1 dtime2*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Computes the difference between *dtime2* and *dtime1* as a number of seconds (a flonum).

**(next-dst-transition&#x20;*****dtime*****)** <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the date and time when the next daylight savings time transition takes place after *dtime*. `next-dst-transition` returns `#f` if there is no daylight savings time for the time zone of *dtime*.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.lisppad.app/libraries/lispkit/lispkit-date-time.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
