local-time - Date and Time Manipulation

Version: 1.0.6
Licence: 3-clause BSD
Repository: dlowe-net/local-time
See also: awesome-cl#date-and-time

In case of any inaccuracies, ambiguities or suggestions, please create an issue here.

Great thanks to the excellent official documentation.

local-time library is a Common Lisp library for the manipulation of dates, times and intervals. It was originally based almost entirely upon Erik Naggum's paper The Long Painful History of Time. Many of the core concepts originated from this paper, such as the seperation of days and seconds, the choice of 2000-03-01 as the standard epoch, and the timestring format.

GETTING STARTED

timestamps and timezones

local-time deals with time in the form of timestamp and timezone.

The following constructs deal with timezones:

Examples

CL-USER> (add-package-local-nickname :lt :local-time)
#<PACKAGE "COMMON-LISP-USER">

CL-USER> (lt:now)
@2020-12-16T13:44:22.493573Z

CL-USER> lt:+asctime-format+
(:SHORT-WEEKDAY #\  :SHORT-MONTH #\  (:DAY 2 #\ ) #\  (:HOUR 2) #\: (:MIN 2)
 #\: (:SEC 2) #\  (:YEAR 4))

CL-USER> (lt:format-timestring nil (lt:now)
                               :format lt:+asctime-format+)
"Wed Dec 16 13:45:24 2020"

CL-USER> (lt:reread-timezone-repository)
NIL

CL-USER> lt::*default-timezone-repository-path*
#P"/home/user/quicklisp/local-projects/local-time/zoneinfo/"

CL-USER> (lt:find-timezone-by-location-name "US/Eastern")
#<LT::TIMEZONE LMT EDT EST EWT EPT>
T

CL-USER> (lt:format-timestring nil (lt:now)
                               :format lt:+asctime-format+
                               :timezone *)
"Wed Dec 16 09:00:57 2020"

See the cookbook for more examples.

Dealing with timestamps

Conversion: to and fro

Querying and Manipulation

Parsing and Formatting

Reader Macros

Clocks

The *clock* special variable and the generic functions clock-now and clock-today are exposed so that applications may re-define the current time or date as required. This can be used for testing or to support alternate clocks.

The currently supported values are:

  • t - Use the standard system clock with no adjustments
  • leap-second-adjusted - The system clock, adjusted for leap seconds using the information in *default-timezone*.

Non-Gregorian Calendars

Support for julian calendars is provided by the following functions:

A note on Portability

This implementation assumes that time zone information is stored in the tzfile format. The default timezone is loaded from /etc/localtime. On non-POSIX systems, this will certainly give different results than the system time handling.

local-time currently supports subsecond precision clocks with allegro, cmucl, sbcl, abcl, and non-Windows ccl. All others will be able to retrieve the time with second precision using get-universal-time. You may add support for your own implementation by implementing the clock generic protocol documented here.

API REFERENCE

*clock*

Variable
Default Value: T

Use this special variable if you need to define your own idea of the current time.

The value of this variable should have the methods clock-now, and clock-today. The currently supported values in local-time are:

TODO: Add / Point to a concrete example of dealing with clocks.

*default-timezone*

Variable
Default Value: #<LOCAL-TIME::TIMEZONE UTC>

This variable contains the timezone that will be used by default if none is specified. It is loaded from /etc/localtime when the library is loaded. If /etc/localtime is not present, it will default to UTC.

+asctime-format+

Variable
Default Value: (:SHORT-WEEKDAY #\  :SHORT-MONTH #\  (:DAY 2 #\ ) #\  (:HOUR 2)
                #\: (:MIN 2) #\: (:SEC 2) #\  (:YEAR 4))

This constant is bound to a format mirroring the output of the POSIX asctime() function. An output with this format will look like this: Sat Mar 1 19:42:34 2008.

+day-names+

Variable
Default Value: #("Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday"
                 "Saturday")

+days-per-week+

Constant: 7

+gmt-zone+

Variable
Default Value: #<LOCAL-TIME::TIMEZONE GMT>

+hours-per-day+

Constant: 24

+iso-8601-date-format+

Variable
Default Value: ((:YEAR 4) #\- (:MONTH 2) #\- (:DAY 2))

See +iso-8601-format+.

+iso-8601-format+

Variable
Default Value: ((:YEAR 4) #\- (:MONTH 2) #\- (:DAY 2) #\T (:HOUR 2) #\:
                (:MIN 2) #\: (:SEC 2) #\. (:USEC 6) :GMT-OFFSET-OR-Z)

This constant is bound to a description of the ISO 8601 format. An output with this format will look like this: 2008-03-01T19:42:34.608506+01:00. This is the default format for the format-timestring function.

+iso-8601-time-format+

Variable
Default Value: ((:HOUR 2) #\: (:MIN 2) #\: (:SEC 2) #\. (:USEC 6))

See +iso-8601-format+.

+iso-week-date-format+

Variable
Default Value: ((:ISO-WEEK-YEAR 4) #\- #\W (:ISO-WEEK-NUMBER 2) #\-
                (:ISO-WEEK-DAY 1))

This constant is bound to a description of the ISO 8601 Week Date format. An output with this format will look like this: 2009-W53-5.

+minutes-per-day+

Constant: 1440

+minutes-per-hour+

Constant: 60

+month-names+

Variable
Default Value: #("" "January" "February" "March" "April" "May" "June" "July"
                 "August" "September" "October" "November" "December")

+months-per-year+

Constant: 12

+rfc-1123-format+

Variable
Default Value: (:SHORT-WEEKDAY ", " (:DAY 2) #\  :SHORT-MONTH #\  (:YEAR 4) #\
                (:HOUR 2) #\: (:MIN 2) #\: (:SEC 2) #\  :GMT-OFFSET-HHMM)

This constant is bound to a description of the format defined in RFC 1123 for Internet timestamps. An output with this format will look like this: Sat, 01 Mar 2008 19:42:34 -0500. See the RFC 1123 for the details about the possible values of the timezone field.

+rfc3339-format+

Variable
Default Value: ((:YEAR 4) #\- (:MONTH 2) #\- (:DAY 2) #\T (:HOUR 2) #\:
                (:MIN 2) #\: (:SEC 2) #\. (:USEC 6) :GMT-OFFSET-OR-Z)

+rfc3339-format/date-only+

Variable
Default Value: ((:YEAR 4) #\- (:MONTH 2) #\- (:DAY 2))

+seconds-per-day+

Constant: 86400

+seconds-per-hour+

Constant: 3600

+seconds-per-minute+

Constant: 60

+short-day-names+

Variable
Default Value: #("Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat")

+short-month-names+

Variable
Default Value: #("" "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct"
                 "Nov" "Dec")

+utc-zone+

Variable
Default Value: #<LOCAL-TIME::TIMEZONE UTC>

A timezone corresponding to UTC.

adjust-timestamp

Macro: (adjust-timestamp timestamp &body changes)

Alters various parts of timestamp, given a list of changes. The changes are in the format (offset part value) and (set part value).

 ;; Return a new timestamp value that points to the previous Monday
 (adjust-timestamp (today) (offset :day-of-week :monday))

 ;; Return a new timestamp value that points three days ahead from now
 (adjust-timestamp (today) (offset :day 3))

Keep in mind that adjust-timestamp is not a mere setter for fields but instead it handles overflows and timezone conversions as expected. Also note that it's possible to specify multiple commands.

The list of possible places to manipulate are: :nsec :sec :sec-of-day :minute :hour :day :day-of-month :month :year.

adjust-timestamp!

Macro: (adjust-timestamp! timestamp &body changes)

Just like adjust-timestamp, but instead of returning a freshly constructed value, it alters the provided timestamp value (and returns it).

all-timezones-matching-subzone

Function: (all-timezones-matching-subzone abbreviated-name)

Returns list of lists of timezone, matched subzone and last transition time for timezones that have subzone matching specified abbreviated-name. Includes both active and historical timezones.

astronomical-julian-date

Function: (astronomical-julian-date timestamp)

Returns the astronomical julian date referred to by the timestamp.

astronomical-modified-julian-date

No documentation found for astronomical-modified-julian-date

clock-now

Generic Function: (clock-now clock)

Returns a timestamp for the current time given a clock. Specialize this generic function to re-define the present moment

clock-today

Generic Function: (clock-today clock)

Returns a timestamp for the current date given a clock. The date is encoded by convention as a timestamp with the time set to 00:00:00UTC.

Specialize this generic function to re-define the present day.

clone-timestamp

Function: (clone-timestamp timestamp)

Returns a copy of timestamp that is timestamp= to it.

date

Type

A timestamp referring to a UTC timezone. The sec slot must be the first second of a day; in other words, the time elements of the timestamp value must have their least possible values 0.

day-of

Generic Function: (day-of object)

Returns the day component of timestamp. Although Naggum's paper specifies that the day should be a signed fixnum, it is left unbounded for flexibility reasons.

days-in-month

Function: (days-in-month month year)

Returns the number of days in the given month of the specified year.

decode-timestamp

Function: (decode-timestamp timestamp &key (timezone *default-timezone*) offset)

Returns the decoded time as multiple values:

(values ns ss mm hh day month year day-of-week daylight-saving-time-p timezone-offset timezone-abbreviation)

define-timezone

Macro: (define-timezone zone-name zone-file &key (load NIL))

Define zone-name (a symbol or a string) as a new timezone, lazy-loaded from zone-file (a pathname designator relative to the zoneinfo directory on this system. If load is true, load immediately.

enable-read-macros

Function: (enable-read-macros)

Enables the local-time reader macros for literal timestamps and universal time.

encode-timestamp

Function: (encode-timestamp nsec sec minute hour day month year &key
           (timezone *default-timezone*) offset into)

Returns a new timestamp instance corresponding to the specified time elements. offset is the number of seconds offset from UTC of the locale. If offset is not specified, the offset will be guessed from the timezone.

If a timestamp is passed as the into argument, its value will be set and that timestamp will be returned. Otherwise, a new timestamp is created.

find-timezone-by-location-name

Function: (find-timezone-by-location-name name)

Returns the timezone found at the location name (such as US/Eastern). reread-timezone-repository must be called before this function is used.

format-rfc1123-timestring

Function: (format-rfc1123-timestring destination timestamp &key
           (timezone *default-timezone*))

See +rfc-1123-format+ and format-timestring.

format-rfc3339-timestring

Function: (format-rfc3339-timestring destination timestamp &key omit-date-part
           omit-time-part (omit-timezone-part omit-time-part) (use-zulu t)
           (timezone *default-timezone*))

Formats a timestring in the RFC 3339 format, a restricted form of the ISO-8601 timestring specification for Internet timestamps.

See +rfc3339-format+ and format-timestring.

format-timestring

Function: (format-timestring destination timestamp &key
           (format +iso-8601-format+) (timezone *default-timezone*))

Constructs a string representation of timestamp according to format and returns it. If destination is T, the string is written to STANDARD-OUTPUT. If destination is a stream, the string is written to the stream.

format is a list containing one or more of strings, characters, and keywords. Strings and characters are output literally, while keywords are replaced by the values here:

:YEAR              *year
:MONTH             *numeric month
:DAY               *day of month
:HOUR              *hour
:MIN               *minutes
:SEC               *seconds
:WEEKDAY           *numeric day of week starting from index 0, which means Sunday
:MSEC              *milliseconds
:USEC              *microseconds
:NSEC              *nanoseconds
:ISO-WEEK-YEAR     *year for ISO week date (can be different from regular calendar year)
:ISO-WEEK-NUMBER   *ISO week number (i.e. 1 through 53)
:ISO-WEEK-DAY      *ISO compatible weekday number (monday=1, sunday=7)
:LONG-WEEKDAY      long form of weekday (e.g. Sunday, Monday)
:SHORT-WEEKDAY     short form of weekday (e.g. Sun, Mon)
:MINIMAL-WEEKDAY   minimal form of weekday (e.g. Su, Mo)
:SHORT-YEAR        short form of year (last 2 digits, e.g. 41, 42 instead of 2041, 2042)
:LONG-MONTH        long form of month (e.g. January, February)
:SHORT-MONTH       short form of month (e.g. Jan, Feb)
:HOUR12            *hour on a 12-hour clock
:AMPM              am/pm marker in lowercase
:GMT-OFFSET        the gmt-offset of the time, in +00:00 form
:GMT-OFFSET-OR-Z   like :GMT-OFFSET, but is Z when UTC
:GMT-OFFSET-HHMM   like :GMT-OFFSET, but in +0000 form
:TIMEZONE          timezone abbrevation for the time

Elements marked by * can be placed in a list in the form

(:keyword padding &optional (padchar #\0))

The string representation of the value will be padded with the padchar.

You can see examples in +ISO-8601-FORMAT+, +ASCTIME-FORMAT+, and +RFC-1123-FORMAT+.

invalid-timestring

Condition

leap-second-adjusted

No documentation found for leap-second-adjusted

make-timestamp

Macro: (make-timestamp &rest args)

Expands to an expression that creates an instance of a timestamp exactly as specified.

modified-julian-date

Function: (modified-julian-date timestamp)

Returns the modified julian date referred to by the timestamp.

now

Function: (now)

Produces a timestamp instance with the current time. Under sbcl, the new timestamp will be precise to the microsecond. Otherwise, the precision is limited to the second.

nsec-of

Generic Function: (nsec-of object)

Returns the microseconds component of the timestamp. Valid values for the nanoseconds range from 0 to 999999999.

parse-rfc3339-timestring

Function: (parse-rfc3339-timestring timestring &key (fail-on-error t)
           (allow-missing-time-part NIL))

parse-timestring

Function: (parse-timestring timestring &key start end (fail-on-error t)
           (time-separator :) (date-separator -) (date-time-separator t)
           (fract-time-separators (quote (. ,))) (allow-missing-elements t)
           (allow-missing-date-part allow-missing-elements)
           (allow-missing-time-part allow-missing-elements)
           (allow-missing-timezone-part allow-missing-elements) (offset 0))

Parses a timestring and returns the corresponding timestamp. Parsing begins at start and stops at the end position. If there are invalid characters within timestring and fail-on-error is T, then an invalid-timestring error is signaled, otherwise NIL is returned.

If there is no timezone specified in timestring then offset is used as the default timezone offset (in seconds).

See local-time::split-timestring for details. Unspecified fields in the timestring are initialized to their lowest possible value, and timezone offset is 0 (UTC) unless explicitly specified in the input string.

reread-timezone-repository

Function: (reread-timezone-repository &key
           (timezone-repository *default-timezone-repository-path*))

Walks the current repository, reading all tzinfo files updating indexes. The default timezone repository is set to the zoneinfo/ directory of the local-time system.

sec-of

Generic Function: (sec-of object)

Returns the seconds component of the timestamp. Valid values for the seconds range from 0 to 86399.

time-of-day

Type

A timestamp with day slot having the value 0.

timestamp

Class

timestamp values are basically instances of

 (defclass timestamp ()
   ((day :type integer)
    (sec :type integer)
    (nsec :type (integer 0 999999999))))

These can represent either a date, a daytime or a time-of-day value, depending on the values of its slots.

timestamp+

Function: (timestamp+ time amount unit &optional (timezone *default-timezone*)
           offset)

Add the amount to the time using the specified unit.

  • unit may be one of ( :nsec :sec :minute :hour :day :month :year).

The value of the parts of the timestamp of higher resolution than the unit will never be touched. If you want a precise number of seconds from a time, you should specify the offset in seconds.

timestamp-

Function: (timestamp- time amount unit &optional (timezone *default-timezone*)
           offset)

Subtract the amount from the time using the specified unit.

  • unit may be one of ( :nsec :sec :minute :hour :day :month :year).

The value of the parts of the timestamp of higher resolution than the unit will never be touched. If you want a precise number of seconds from a time, you should specify the offset in seconds.

timestamp-century

Function: (timestamp-century timestamp &key (timezone *default-timezone*))

Returns the ordinal century upon which the timestamp falls. Ordinal time values start at 1, so the (timestamp-century (now)) will return 21.

timestamp-day

Function: (timestamp-day timestamp &key (timezone *default-timezone*))

Returns the day of the month upon which the timestamp falls.

timestamp-day-of-week

Function: (timestamp-day-of-week timestamp &key (timezone *default-timezone*)
           offset)

This returns the index of the day of the week, starting at 0 which means Sunday.

Note: "Day of the week" is ambigous and locale dependent.

timestamp-decade

Function: (timestamp-decade timestamp &key (timezone *default-timezone*))

Returns the cardinal decade upon which the timestamp falls. Ordinal time values start at 1.

timestamp-difference

Function: (timestamp-difference time-a time-b)

Returns the difference between time-a and time-b in seconds

timestamp-hour

Function: (timestamp-hour timestamp &key (timezone *default-timezone*))

timestamp-maximize-part

Function: (timestamp-maximize-part timestamp part &key
           (timezone *default-timezone*) into)

Returns a timestamp with its parts maximized up to part. part can be any of (:nsec :sec :min :hour :day :month). If into is specified, it will be modified and returned, otherwise a new timestamp will be created.

timestamp-maximum

Function: (timestamp-maximum time &rest times)

Returns the latest timestamp

timestamp-microsecond

Function: (timestamp-microsecond timestamp)

timestamp-millennium

Function: (timestamp-millennium timestamp &key (timezone *default-timezone*))

Returns the ordinal millennium upon which the timestamp falls. These start from 1, so the (timestamp-millennium (now)) will return 3.

timestamp-millisecond

Function: (timestamp-millisecond timestamp)

timestamp-minimize-part

Function: (timestamp-minimize-part timestamp part &key
           (timezone *default-timezone*) into)

Returns a timestamp with its parts minimized up to part. part can be any of (:nsec :sec :min :hour :day :month). If into is specified, it will be modified and returned, otherwise a new timestamp will be created.

timestamp-minimum

Function: (timestamp-minimum time &rest times)

Returns the earliest timestamp

timestamp-minute

Function: (timestamp-minute timestamp &key (timezone *default-timezone*))

timestamp-month

Function: (timestamp-month timestamp &key (timezone *default-timezone*))

Returns the month upon which the timestamp falls.

timestamp-second

Function: (timestamp-second timestamp &key (timezone *default-timezone*))

timestamp-subtimezone

Function: (timestamp-subtimezone timestamp timezone)

Return as multiple values the time zone as the number of seconds east of UTC, a boolean daylight-saving-p, and the customary abbreviation of the timezone.

timestamp-to-universal

Function: (timestamp-to-universal timestamp)

Return the UNIVERSAL-TIME corresponding to the timestamp. This is the date/time specified in timestamp encoded as the number of seconds since January 1st, 1900 12:00am UTC.

timestamp-to-unix

Function: (timestamp-to-unix timestamp)

Return the Unix time corresponding to the timestamp. This returns the date/time specified in timestamp encoded as the number of seconds since January 1st, 1970 12:00am UTC. It corresponds with the time received from the POSIX call time().

timestamp-week

No documentation found for timestamp-week

timestamp-whole-year-difference

Function: (timestamp-whole-year-difference time-a time-b)

Returns the number of whole years elapsed between time-a and time-b.

Note: This is useful for calculating anniversaries and birthdays.

timestamp-year

Function: (timestamp-year timestamp &key (timezone *default-timezone*))

Returns the cardinal year upon which the timestamp falls.

timestamp/=

Function: (timestamp/= &rest timestamps)

Returns T if no pair of timestamps is equal. Otherwise return NIL.

timestamp<

Function: (timestamp< &rest times)

timestamp<=

Function: (timestamp<= &rest times)

timestamp=

Function: (timestamp= &rest times)

timestamp>

Function: (timestamp> &rest times)

timestamp>=

Function: (timestamp>= &rest times)

timezones-matching-subzone

Function: (timezones-matching-subzone abbreviated-name timestamp)

Returns list of lists of active timezone, matched subzone and last transition time for timezones that have subzone matching specified abbreviated-name as of timestamp moment if provided.

to-rfc1123-timestring

Function: (to-rfc1123-timestring timestamp)

to-rfc3339-timestring

Function: (to-rfc3339-timestring timestamp)

today

Function: (today)

Produces a timestamp instance that corresponds to today's date, which is the midnight of the current day in the UTC zone.

universal-to-timestamp

Function: (universal-to-timestamp universal &key (nsec 0))

Produces a timestamp instance from the provided universal time universal. Universal time is defined in the Common Lisp Specification as the number of seconds since 1900-01-01T00:00:00Z.

Note: Subsecond precision is not preserved.

unix-to-timestamp

Function: (unix-to-timestamp unix &key (nsec 0))

Produces a timestamp instance from the provided unix time unix. Unix time is defined by POSIX as the number of seconds since 1970-01-01T00:00:00Z.

with-decoded-timestamp

Macro: (with-decoded-timestamp
        (&key nsec sec minute hour day month year day-of-week daylight-p
         timezone offset)
        timestamp &body forms)

This macro binds variables to the decoded elements of timestamp. The timezone argument is used for decoding the timestamp, and is not bound by the macro. The value of day-of-week starts from 0 which means Sunday.

zone-name

Function: (zone-name zone)