diff options
author | Hugo Hörnquist <hugo@lysator.liu.se> | 2022-03-15 11:19:58 +0100 |
---|---|---|
committer | Hugo Hörnquist <hugo@lysator.liu.se> | 2022-03-28 14:17:01 +0200 |
commit | 5db7377ba2c3891420415506b00c20febb8639f9 (patch) | |
tree | da5bd0a65cc553d6b3290db6062c98e664f613cd /doc/ref/guile | |
parent | Add comment about why browserify. (diff) | |
download | calp-5db7377ba2c3891420415506b00c20febb8639f9.tar.gz calp-5db7377ba2c3891420415506b00c20febb8639f9.tar.xz |
Add texinfo doc for (datetime).
Diffstat (limited to 'doc/ref/guile')
-rw-r--r-- | doc/ref/guile/datetime.texi | 680 |
1 files changed, 680 insertions, 0 deletions
diff --git a/doc/ref/guile/datetime.texi b/doc/ref/guile/datetime.texi new file mode 100644 index 00000000..d49c4ada --- /dev/null +++ b/doc/ref/guile/datetime.texi @@ -0,0 +1,680 @@ +@node Datetime +@section Datetime + +My datetime library, with focus on date manipulation in ways sensible +for humans. So that a date-time plus one day always keep the time of +day. +For example, 26 mars 2022 10:00 plus 1 day would give 27 mars 2022 +10:00, even though 25 hours have passed due to summer time starting +(in Sweden). + +Note that while some of these procedures mentions timezones, almost +nothing is actually done with it. + +@subsection Constants + +@defvar jan +@defvarx january +@defvarx feb +@defvarx february +@defvarx mar +@defvarx mars +@defvarx apr +@defvarx april +@defvarx may +@defvarx jun +@defvarx june +@defvarx jul +@defvarx july +@defvarx aug +@defvarx august +@defvarx sep +@defvarx september +@defvarx oct +@defvarx october +@defvarx nov +@defvarx november +@defvarx dec +@defvarx december +Numeric constants for all months. +@code{@var{jan} = 1}, @code{@var{dec} = 12}. +@end defvar + +@defvar sun +@defvarx sunday +@defvarx mon +@defvarx monday +@defvarx tue +@defvarx tuesday +@defvarx wed +@defvarx wednesday +@defvarx thu +@defvarx thursday +@defvarx fri +@defvarx friday +@defvarx sat +@defvarx saturday +@anchor{sunday} +Numeric constants for all weekdays. +@code{@var{sunday} = 0}, @code{@var{saturday} = 6}. +@end defvar + +@subsection Parameters and Configuration + +@deftp {parameter} week-start +@anchor{week-start} +Which weekday should be considered the first. Used for calculating +week numbers, the start dates of week, and is available for UI-code +and the like which wants it. +@end deftp + +@deftp {config} week-start +Configuration item, updates @xref{week-start}. +@end deftp + + +@subsection Datatypes + +@deftp {Immutable Record} <date> year month day +Object representing a date, without any timezone information. +Given the date 2040-03-23 (in ISO-8601 format), @var{year} = 2020, +@var{month} = 3 and @var{day} = 23. + +Values higher than those usually used are possible, but not recommended. + +@defun date? x +Is @var{x} a date object? +@end defun + +@defun date [#:year=0] [#:month=0] [#:day=0] +Create a new date object. +@end defun + +@defun year <date> +@defunx month <date> +@defunx day <date> +Fetch corresponding field from the date object. +@end defun +@end deftp + +@deftp {Immutable Record} <time> hour minute second +Object representing a timestamp in a given day, +without any timezone information. +Given the time 10:20:30, @var{hour} = 10, +@var{minute} = 20 and @var{second} = 30. + +Values larger than the ``regular'' are allowed, and useful since this +type is also used for time offsets. + +@defun time? x +Is @var{x} a time object? +@end defun + +@defun time [#:hour=0] [#:minute=0] [#:second=0] +Create a new time object. +@end defun + +@defun hour <time> +@defunx minute <time> +@defunx second <time> +Fetch corresponding field from the time object. +@end defun +@end deftp + + +@deftp {Immutable Record} <datetime> date time tz + +A collation of date and time, along with an optional timezone. +Set @code{tz = #f} if a timezone is not desired. + +@defun datetime? x +Is @var{x} a datetime object? +@end defun + +@defun datetime [#:date] [#:time] [#:tz] [#:year=0] [#:month=0] [#:day=0] [#:hour=0] [#:minute=0] [#:second=0] +Creates a new <datetime>. If @var{date} or @var{time} is given, those +are used. Otherwise, a date object is created from @var{year}, +@var{month} and @var{day}, and time is respectively created from +@var{hour}, @var{minute} and @var{second}. +@end defun + +@defun get-date +@defunx get-timezone +Note that @code{get-time} doesn't exists. +@end defun +@end deftp + + +@subsection Reader Extensions + +This module registers reader extensions on @code{#0}, @code{#1}, and +@code{#2}. These read either dates, times, or datetimes; using @code{string->date/-time}. + +@c @subsection CTIME + +@c These procedures are for interfacing with C's time procedures, see CTIME(3). + +@c The datetime<->tm procedures are internal, since they are slightly +@c unstable (see comments in code). +@c They are thereby not documented. +@c @defun datetime->tm datetime +@c Convert a @code{<datetime>} object to a @code{struct tm}, encoded in a +@c scheme vector. +@c @end defun +@c +@c @defun tm->datetime tm +@c Converts a @code{struct tm}, as returned from @code{datetime->tm} back +@c into a @code{<datetime>} object. +@c @end defun + +@subsection Procedures + +@defun datetime->unix-time datetime +Converts @var{datetime} to an integer representing its unix time. +@end defun + +@defun unix-time->datetime n +Converts a given unix timestamp to a datetime object. +Currently forces the timezone to be UTC. +@end defun + +@defun current-datetime +Return a datetime object of the current date and time. +Currently always returns it in UTC. +@end defun + +@defun current-date +Get the date component from a call to @code{current-datetime}. +@end defun + + +@defun get-datetime datetime +Takes a datetime in any timezone, and renormalize it to local time (as +defined by the environment variable TZ). This means that given UTC +10:00 new years day would return 11:00 new years day if ran in sweden. +@end defun + + +@defun as-date date/-time +@defunx as-time date/-time +Both procedures takes a <date>, <time>, or <datetime>, and return +respectively a <date> or <time> object. + +@code{as-date}, when given a time will return a zeroed date object. +Vice versa for @code{as-time}. +@end defun + +@defun as-datetime date/-time +Takes a <date>, <time>, or <datetime>, and returns a <datetime> object +with the same data, with the (possibly) missing date or time set to +all zeroes. +@end defun + + +@defun date-zero? date +@defunx time-zero? time +Checks if all components are zero. +@end defun + + +@defun leap-year? year +Given an integer @var{year}, return @code{#t} if it's a leap year, and +@code{#f} otherwise. +@end defun + +@defun days-in-month date +Returns how many days are in the month specified by the <date> @var{date}. +Note that the day component is ignored. +@end defun + +@defun days-in-year date +Returns how many days are in the year pointed to by @var{date}. +@end defun + +@defun start-of-month date +Returns a <date> object equal to date, but with the day component set +to 1. +@end defun + +@defun end-of-month date +Returns a <date> object equal to date, but with the day component set +to the last day of the month. + +@example +(end-of-month #2020-01-10) +⇒ #2020-01-31 +(end-of-month #2020-02-01) +⇒ #2020-02-29 +@end example +@end defun + + +@defun start-of-year date +Returns a <date> object equal to date, but with the day and month +component set to 1. +@end defun + +@defun date-stream date-increment start-day +Returns an @ref{(guile)SRFI-43} stream of <date> objects, starting at +@var{start-day} and stepping in increments of @var{date-increment}. +@end defun + +@defun day-stream start-day +Returns a stream of each day from @var{start-day}. +@end defun + +@defun month-stream start-day +Returns a stream of each months from @var{start-day}. +Day component stays the same. +@end defun + +@defun week-stream start-day +Returns a stream of each week from @var{start-day} +(increments of 7 days). +@end defun + +@defun time-min a b +@defunx time-max a b +@defunx date-min a b +@defunx date-max a b +@defunx datetime-min a b +@defunx datetime-max a b +Returns the smaller (or larger) of @var{a} or @var{b}. +@end defun + +@defun month+ date [change=1] +@defunx month- date [change=1] +Equivalent to @code{(date+ date (date month: change))}. +@end defun + +@defun week-day date +Returns an integer representing the week day of @var{date}. +@ref{sunday} +@end defun + + +@defun week-1-start date [week-start=(week-start)] +Returns the date which week 1 starts on, according to the (at least) +Swedish rule of week counting. +@ref{week-start} +@end defun + + +@defun week-number date [week-start=(week-start)] +Returns the week number of @var{date}, according to the (at least) +Swedish rule of week counting. +@ref{week-start} +@end defun + +@defun date-starting-week week-number date [week-start=(week-start)] +Returns the first day of week @var{week-number}, @var{date} is used +for year information. +@ref{week-start} +@end defun + + +@defun week-day-name week-day [truncate-to] [#:key locale] +Returns the locale dependent name for the given week day. + +@var{week-day} is a number per @ref{sunday}. +@var{truncate-to} may be a number, which limits to the first @var{n} +letters of the resulting string. +@end defun + + +@defun timespan-overlaps? s1-begin s1-end s2-begin s2-end +Check if the interval @var{s1-begin} to @var{s1-end} overlaps with the +interval @var{s2-begin} to @var{s2-end}. +@end defun + +@defun find-first-week-day week-day date +Returns the first instance of the given week-day after @var{date}. + +@example +(find-first-week-day mon #2020-04-01) +⇒ #2020-04-06 +(find-first-week-day mon #2020-04-10) +⇒ #2020-04-13 +(find-first-week-day mon #2020-04-30) +⇒ #2020-05-04 +@end example +@end defun + +@defun all-wday-in-month week-day month-date +Returns instances of the given week-day in month between +month-date and end of month. +@example +(all-wday-in-month mon #2020-06-01) +⇒ (#2020-06-01 #2020-06-08 #2020-06-15 #2020-06-22 #2020-06-29) +(all-wday-in-month mon #2020-06-10) +⇒ (#2020-06-15 #2020-06-22 #2020-06-29) +@end example +@end defun + +@defun all-wday-in-year week-day year-date +Returns a list of all instances of @var{week-day} in @var{year-date}. +@end defun + +@defun add-day date +@defunx remove-day date +@code{@var{date} ± (date day: 1)} +@end defun + +@defun in-date-range? start-date end-date → date → boolean +Returns a predicate procedure, which checks if a given date is between +@var{start-date} and @var{end-date}. +@end defun + +@defun weekday-list [week-start=(week-start)] +Returns a list of the seven week days, with @var{week-start} +as the beginning of the week. +@end defun + + +@defun start-of-week d [week-start=(week-start)] +@defunx end-of-week d [week-start=(week-start)] +Returns the date the week containing @var{d} started or ended. +@end defun + + +@defun month-days date [week-start=(week-start)] +Given a month and and which day the week starts on, +returns three lists, which are: +The days leading up to the current month, but share a week +The days in the current month +The days after the current month, but which shares a week. + +@example + mars 2020 +må ti on to fr lö sö + 1 + 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 +16 17 18 19 20 21 22 +23 24 25 26 27 28 29 +30 31 +@end example +@lisp +(month-days #2020-03-01 mon) +; ⇒ (2020-02-24 ... 2020-02-29) +; ⇒ (2020-03-01 ... 2020-03-31) +; ⇒ (2020-04-01 ... 2020-04-05) +@end lisp +Ignores day component of @var{date}. +@end defun + + +@defun days-in-interval start-date end-date +The amount of days in the given interval, including both endpoints. +@end defun + + +@defun year-day date +Day from start of the year, so 1 feb would be day 32. +Also known as Julian day. +@end defun + + +@defun time->decimal-hour time +Convert @var{time} to a decimal value, so 10:30 would become 10.5. +@end defun + +@defun datetime->decimal-hour dt [start-date] +Similar to @code{time->decimal-hour}, but also looks at the date component. + +@var{start-date} is required if either the month of year component of +@var{dt} is non-zero (since months and years have a variable number of hours). +@end defun + +@defun date-range start end [increment=(date day: 1)] +Returns a list of all dates from start to end. +Both inclusive +@end defun + +@defun locale-month +@defunx locale-month-short +These are direct re-exports from (ice-9 i18n) + +@xref{Accessing Locale Information,,,guile}. +@end defun + +@defun date= args ... +@defunx date=? args ... +@defunx date< args ... +@defunx date<? args ... +@defunx date> args ... +@defunx date>? args ... +@defunx date<= args ... +@defunx date<=? args ... +@defunx date>= args ... +@defunx date>=? args ... +Checks if all date arguments satisfy the predicate. +@end defun + +@defun time= args ... +@defunx time=? args ... +@defunx time< a b +@defunx time<? a b +@defunx time> a b +@defunx time>? a b +@defunx time<= a b +@defunx time<=? a b +@defunx time>= a b +@defunx time>=? a b +Checks if all time arguments satisfy the predicate. +@end defun + +@defun datetime= args ... +@defunx datetime=? args ... +@defunx datetime< a b +@defunx datetime<? a b +@defunx datetime> a b +@defunx datetime>? a b +@defunx datetime<= a b +@defunx datetime<=? a b +@defunx datetime>= a b +@defunx datetime>=? a b +Check if all datetime arguments satisfy the predicate. +The timezone field is ignored. +@end defun + +@defun date/-time< a b +@defunx date/-time<? a b +@defunx date/-time> a b +@defunx date/-time>? a b +@defunx date/-time<= a b +@defunx date/-time<=? a b +@defunx date/-time>= a b +@defunx date/-time>=? a b +Equivalent to the @code{datetime*} versions, but wraps its arguments +in @code{as-datetime}. +@end defun + +@subsection Arithmetic + +While only one date (and one time) type is available, it really should +be seen as two. Absolute dates, such as the fourth of november, +2022. The other type are intervals, such as 3 years, 4 months and 2 days. + +A ``type mismatch'' might therefore lead to some confounding results. +@example +(date- #2020-01-01 #2020-01-01) +⇒ #00-1-11-31 +(date-difference #2020-01-01 #2020-01-01) +⇒ #0000-00-00 +@end example + +@defun date+ base rest ... +@defunx date- base rest ... +Add or remove each difference from base. +@end defun + +@defun date-difference end start +Returns difference between the two dates, in years, months, and days. +In such a way that + +@lisp +(date= (date+ start (date-difference end start))) +@end lisp +@end defun + +@defun time+ base rest ... +@defunx time- base rest ... +Adds (or subtracts) each difference from the base, and returns two +values. The sum, and how many midnight's have passed. + +@lisp +(time+ #22:00:00 (time hour: 4)) +⇒ #02:00:00 +⇒ 1 +@end lisp +@end defun + +@defun datetime+ base change +@defunx datetime- base change +@end defun + +@defun datetime-difference end start +@end defun + +@subsection Parsing and Formatting + +@defun datetime->string datetime [fmt=''~Y-~m-~dT~H:~M:~S''] [#:allow-unknown?] + +Formats @var{datetime} into a string. +The function will throw an error when encountering an unknown format +specifier, unless @var{#:allow-unknown} is true. + +@table @samp +@item ~~ +A literal tilde (~). +@item ~H +Hour, left padded with zeroes to length 2. +@item ~k +Like @samp{~H}, but padded with spaces. +@item ~M +Minute, left padded with zeroes to length 2. +@item ~S +Seconds, left padded with zeroes to length 2. +@item ~Y +Year, left padded with zeroes to length 4; +@item ~m +Month number, left padded with zeroes to length 2. +@item ~d +Day in month, left padded with zeroes to length 2. +@item ~s +Epoch time, per UNIX. +@item ~e +Same as @samp{~d}, but padded with spaces. +@item ~1 +Shorthand for @samp{~Y-~m-~d}. +@item ~3 +Shorthand for @samp{~H:~M:~S}. +@item ~A +Locale week day name. +@item ~a +Locale week day name, truncated to 3 characters. +@item ~b +Locale month name, truncated. +@item ~B +Locale month name, in full. +@item ~Z +@samp{Z} if the timezone is @samp{UTC}. Nothing otherwise. +@end table +@end defun + +@defun date->string date [fmt=''~Y-~m-~d''] [#:allow-unknown?] +@defunx time->string date [fmt=''~H:~M:~S''] [#:allow-unknown?] +Simple wrappers around @code{datetime->string}, which works directly +on date or time objects. +@end defun + + +@defun string->datetime str [fmt=''~Y-~m-~dT~H:~M:~S~Z''] [locale=%global-locale] +Attempts to parse @var{str} as a datetime, according to the ruleset @var{fmt}. +An invalid or unparsable string will throw an error. + +Each token in @var{fmt} informs the parser what the next expected +token in @var{str} is. If a binding rule is parsed multiple times, +then the last one is used for the resulting object. For example, +@example +(string->datetime "10:20" "~H:~H") +⇒ (datetime hour: 20) +@end example + +spaces are literal, there is no way to match an arbitrary number of +whitespace characters + +@table @samp +@item ~~ +Next token is a literal tilde. + +@item ~Z +If next token is a literal @samp{Z} then the resulting timezone is set +to @samp{UTC}, otherwise does nothing. + +@item ~p +The next token is an AM/PM indicator, matched by the regex +@code{^([AaPp])[.]?[Mm][.]?}. A valid token will reinterpret the last +hour indicator as 12-hour time (instead of 24 hour time), regardless +if its before or after this token. + +@item ~b +@itemx ~B +@itemx ~h +Parses a month by name, just as @code{parse-month}. + +@item ~H +@itemx ~M +@itemx ~S +@itemx ~m +@itemx ~d +Parses up to two digits, but possibly less if a non-digit appears in +the string. Then stores the resulting value in either the hour, +minute, second, month, or day slot of the resulting object. + +This double function allows both dates without delimiters, such as +``0102'' to be correctly parsed, but also more free form formats, such +as ``1 jan''. + +@item ~Y +Equivalent to @samp{~H}, but reads up to 4 digits, and stores the +result in the year field. +@end table +@end defun + + +@defun parse-month str [locale=%global-locale] +Returns the first month whose name has @var{str} as its prefix. +The result will be on the interval [1, 12], or -1 if no month matched. +@end defun + + +@defun string->time str [fmt=''~H:~M:~S''] [locale=%global-locale] +@defunx string->date str [fmt=''~Y-~m-~d''] [locale=%global-locale] +Wrappers around @code{string->datetime}, but only returning the time +or date component. +@end defun + + +@defun string->date/-time string +Parses string as an ISO-8601 string. Checks for the existence of +@code{T}, @code{:}, or @code{-} to determine if it's a datetime, time +or date. +@end defun + +@defun parse-ics-date str +@defunx parse-ics-time str +@defunx parse-ics-datetime str [zone] +Parses dates per RFC5545. +@end defun + +@defun parse-iso-date str +@defunx parse-iso-time str +@defunx parse-iso-datetime str +Parses (the well known subset) of ISO-compatible dates. +@end defun + +@defun parse-freeform-date str +Currently an alias for parse-iso-datetime, but should preferably be extended. +@end defun |