This library can handle two quite different notations for time periods, one lispy and one modeled on the syntax used by cfengine's class notation. It was written to be used in long-running lisp processes doing various kinds of system (computer) and environmental monitoring, so I could say "don't page me at 3am about this" or "don't worry about this on weekends." A Python version of this library was useful, so I've made this CL version public, too.
The library depends on the behavior of your lisp's implementation of DECODE-UNIVERSAL-TIME. It cannot currently be told to compare a period against different time zones.
The keyword-heavy list notation for time periods is:
All of these period notations except :class have a range version (:year-range y1 y2). All of the ranges understand that time cycles, so that (:hour-range 22 8) does the correct thing. You may indicate a year range with the first value larger than the second, but a GIBBERISH-CYCLING-YEAR-RANGE warning will be signaled about it. (:year-range 2008 2005) is effectively (not (:year-range 2006 2007)). All ranges are inclusive, which may do surprising things for hours (see string notation for ranges).
The case-insensitive string period notation is:
The boolean operators, in order of precedence, are
Precedence may be forced by using parentheses, May.(Monday|Wednesday|Friday).
There are two range notations for the strings. Most of the time, at least for English speakers, time ranges are inclusive, "Monday - Friday," for example. In hours, however, most of the time and for most people 2-4 means 2:00-3:59. The default range notation, Hr2-4, however, means 2:00-4:59. There are therefore two ways to indicate a range with period strings:
Most of the time the exclusive range will be used only with hours.
Some basic use:
PERIOD> (in-period-p '(:minute-range 0 30)) T PERIOD> (in-period-p '(or (:day-of-week :tuesday) (:minute-range 0 30))) T PERIOD> (in-period-p "Saturday-Wednesday.April.Yr2008") T
The package name is :cl-period with a single nickname, :period.
It depends on CL-YACC.
You will need LIFT to run the unit tests.
This base error condition isn't directly signalled, but is the parent of the three error conditions below.
A time period or range was called with too many, or too few, arguments.
A time period or range was called with values that made no sense for the given period (say, Hour 74).
The string parser wasn't able to decipher a period string.
warning condition gibberish-cycling-year-range
Raised when the first part of a year range is greater than the second part. Feel free to muffle this on your own if you think this sort of range makes sense.
If the string syntax is really broken CL-YACC will pass up parsing conditions.
There are no restarts.
function compile-period-string period-string => period-list
Converts a string period into the lispy period format. May signal any of the conditions and the warning listed above.
generic function in-period-p period &optional (time (get-universal-time)) => boolean
Takes either a string or list period and returns t or nil if the given period matches the time. A string will have to be compiled before being tested, so frequently run period checks should probably precompile all periods. Some future version may memoize these string periods. See Speed.
generic function define-period-class name period => period-list
Adds new classes which are stored in the global variable *PERIOD-CLASSES*. The class name may be either a keyword or a string (which will be coerced to a keyword). The period may be either a string or list period representation:PERIOD> (define-period-class :weekend "Saturday-Sunday") (:DAY-OF-WEEK-RANGE :SATURDAY :SUNDAY) PERIOD> (in-period-p "Monday|Weekend") T