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:
- *default-timezone*
- +utc-zone+
- define-timezone
- find-timezone-by-location-name
- reread-timezone-repository
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
- now
- today
- days-in-month
- universal-to-timestamp
- unix-to-timestamp
- timestamp-to-universal
- timestamp-to-unix
- make-timestamp
- clone-timestamp
- encode-timestamp
- decode-timestamp
- with-decoded-timestamp
Querying and Manipulation
- day-of
- sec-of
- nsec-of
- timestamp<
- timestamp<=
- timestamp>
- timestamp>=
- timestamp=
- timestamp/=
- timestamp-minimum
- timestamp-maximum
- timestamp-whole-year-difference
- timestamp+
- timestamp-
- timestamp-maximize-part
- timestamp-minimize-part
- adjust-timestamp
- adjust-timestamp!
- timestamp-subtimezone
- timestamp-day-of-week
- timestamp-millennium
- timestamp-century
- timestamp-decade
- timestamp-year
- timestamp-month
- timestamp-day
- timestamp-hour
- timestamp-minute
- timestamp-second
- timestamp-millisecond
- tiemstamp-microsecond
Parsing and Formatting
- +iso-8601-format+
- +asctime-format+
- +rfc-1123-format+
- +iso-week-date-format+
- parse-timestring
- format-timestring
- format-rfc3339-timestring
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 adjustmentsleap-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:
t
- use the standard clock- leap-second-adjusted - use a clock which adjusts for leap seconds using the information in *default-timezone*.
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)