Evaluating: the periods library
vindarel opened this issue · 1 comments
bo-tato:
The periods library you might want to consider inclusion in CIEL, it has convenient macros like do-times there for looping over a range of dates.
I've written a couple standalone ciel scripts with it. Like this for catching up on reading the #commonlisp irc channel.
- periods: https://github.com/jwiegley/periods/
- documentation: very few, in texinfo files: https://github.com/jwiegley/periods/blob/master/doc/docstrings/
periods
might bring some more high-level functions and macros, complementing local-time
.
goal: bring the good in a common package, for instance import & reexport symbols into a new ciel/time
package.
do-times
not exported
Signature
((var start duration end &optional (result)) &body body)
A 'do' style version of the functional MAP-TIMES macro.
The disadvantage to DO-TIMES is that there is no way to ask for a reversed
time sequence, or specify an inclusive endpoint.
example:
do-times (day (-> +last-date-file+ str:from-file str:trim parse-timestring)
(duration :days 1)
(today))
…)
also do-time-period
(un-exported), do-over-time
(exported but doesn't exist?), map-over-time
(doesn't exist ?)
subtract-time, add-time
equivalent to local-time:timestamp-
?
(periods:subtract-time (local-time:now) (periods:duration :days 2))
==
(local-time:timestamp- (local-time:now) 2 :day)
not exported: add-[hours, days, years, months, minutes, seconds, microseconds, milliseconds]
(periods::add-hours (periods:duration :days 1) 3)
#S(PERIODS:DURATION
:YEARS 0
:MONTHS 0
:DAYS 1
:HOURS 3
:MINUTES 0
:SECONDS 0
:MILLISECONDS 0
:MICROSECONDS 0
:NANOSECONDS 0)
duration
(periods:duration :days 3)
#S(PERIODS:DURATION
:YEARS 0
:MONTHS 0
:DAYS 3
:HOURS 0
:MINUTES 0
:SECONDS 0
:MILLISECONDS 0
:MICROSECONDS 0
:NANOSECONDS 0)
time-range
(periods:time-range :begin (local-time:now) :end (local-time:now))
#S(PERIODS:TIME-RANGE
:FIXED-BEGIN NIL
:BEGIN @2023-11-09T14:21:56.804175+01:00
:BEGIN-INCLUSIVE-P T
:FIXED-END NIL
:END @2023-11-09T14:21:56.804177+01:00
:END-INCLUSIVE-P NIL
:DURATION NIL
:ANCHOR NIL)
fixed-time
Signature
(&rest args)
Return a fixed point in time relative to the time of the call. ARGS is a
property list giving a specific precision for the return value.
If the keyword argument :NOW is given, all else is ignored; this is
equivalent to calling LOCAL-TIME:NOW.
Otherwise, any keyword arguments given override their corresponding elements
in the current time. Further, any elements smaller in resolution than the
finest specified element are reduced to 0 or 1, according to their position.
For example, assuming the current time is "@2007-11-17T23:02:00.000",
compare these outputs:
(fixed-time :month 4) => @2007-04-01T00:00:00.000
(fixed-time :day 10) => @2007-11-10T00:00:00.000
(fixed-time :hour 15) => @2007-11-17T15:00:00.000
This behavior makes it very easy to return a fixed time for "april of this
year", etc. If you wish to determine the date of the previous April, while
preserving the current day of the month, hour of the day, etc., then see the
function PREVIOUS-TIME.
parse-time-range, parse-time-period
Parse a human-readable string and give a time-range, or parse a date with a time-range of 1 day.
(periods:parse-time-range "2 months")
#S(PERIODS:TIME-RANGE
:FIXED-BEGIN NIL
:BEGIN @2023-11-09T00:00:00.000000+01:00
:BEGIN-INCLUSIVE-P T
:FIXED-END NIL
:END NIL
:END-INCLUSIVE-P NIL
:DURATION #S(PERIODS:DURATION
:YEARS 0
:MONTHS 2
:DAYS 0
:HOURS 0
:MINUTES 0
:SECONDS 0
:MILLISECONDS 0
:MICROSECONDS 0
:NANOSECONDS 0)
:ANCHOR NIL)
Possible strings:
(defun time-parser-tests ()
(dolist
(expr '("this year"
"next year"
"last year"
"the year before last"
"jan 8"
"jan 2008"
"2008/01/01"
"2 months"
"2 months since jan 8"
"january of last year"
"three months ago"
"1 months, 2 days ago"
"every friday starting tomorrow"
"every day this week"
"every day of this week"
"every ten days"
"the day after tuesday"
"monthly"
"monthly from the beginning of this year"
"monthly from now until the end of the year"
"the last week of last year"
;; "every weekend this year"
))
(format t "EXPR < ~A~% >= ~S~%" expr
(p/time (make-string-input-stream expr)))))
- is this correct?
(periods:parse-time-range "every day this week")
@2023-11-09T00:00:00.000000+01:00
;; no time-range structure?
Convenience functions
current-year
leapp
local-time has it in a flet, my PR to bring it to an accessible function got rejected: dlowe-net/local-time#106 (add weaks-in-year, leap-year-p, tomorrow, yesterday)
falls-on-weekend-p
sleep-until
it doesn't have tests? (I know it's CL, but still)
Added the current periods doc online, with syntax highlighting: https://lisp-maintainers.github.io/periods/
It should be extended now (and probably by using a real documentation builder).
While working on the doc, ciel -s simplehttpserver
was helpful ;)