Regarding a schema that allows for events to occur at various one-shot and
recurrent times... There exist both a well-known and standardized format, and
a lesser-known but more powerful format, that allows for this. Each is
described briefly here. In particular, it would be really nice if we could
incorporate all of the capabilities of the second format.
Format 1: Crontab
-----------------
The well-known format is the one used by the Unix/Linux utility "cron" and
described in the "crontab(5)" manual section. Although these fields would be
in the database rather than in a text file, the following excerpt from the
manual section describes the utility of this format. (We'd want to add a
"year" field in addition to those described here.)
The time and date fields are:
field allowed values
----- --------------
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names, see below)
day of week 0-7 (0 or 7 is Sun, or use names)
A field may be an asterisk (*), which always stands for
''first-last''.
Ranges of numbers are allowed. Ranges are two numbers
separated with a hyphen. The specified range is inclu-
sive. For example, 8-11 for an ''hours'' entry specifies
execution at hours 8, 9, 10 and 11.
Lists are allowed. A list is a set of numbers (or ranges)
separated by commas. Examples: ''1,2,5,9'', ''0-4,8-12''.
Step values can be used in conjunction with ranges. Fol-
lowing a range with ''/<number>'' specifies skips of the
number's value through the range. For example, ''0-23/2''
can be used in the hours field to specify command execu-
tion every other hour (the alternative in the V7 standard
is ''0,2,4,6,8,10,12,14,16,18,20,22''). Steps are also
permitted after an asterisk, so if you want to say ''every
two hours'', just use ''*/2''.
Names can also be used for the ''month'' and ''day of
week'' fields. Use the first three letters of the partic-
ular day or month (case doesn't matter). Ranges or lists
of names are not allowed.
The ''sixth'' field (the rest of the line) specifies the
command to be run. The entire command portion of the
line, up to a newline or % character, will be executed by
/bin/sh or by the shell specified in the SHELL variable of
the cronfile. Percent-signs (%) in the command, unless
escaped with backslash (\), will be changed into newline
characters, and all data after the first % will be sent to
the command as standard input.
Note: The day of a command's execution can be specified by
two fields -- day of month, and day of week. If both
fields are restricted (ie, aren't *), the command will be
run when either field matches the current time. For exam-
ple,
''30 4 1,15 * 5'' would cause a command to be run at 4:30
am on the 1st and 15th of each month, plus every Friday.
Example Cron File
# use /bin/sh to run commands, no matter what /etc/passwd says
SHELL=/bin/sh
# mail any output to 'paul', no matter whose crontab this is
MAILTO=paul
#
# run five minutes after midnight, every day
5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# run at 2:15pm on the first of every month -- output mailed to paul
15 14 1 * * $HOME/bin/monthly
# run at 10 pm on weekdays, annoy Joe
0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun echo "run at 5 after 4 every sunday"
Format 2: Xemacs Calendar
-------------------------
The lesser-known format is used by xemacs in its calendar/diary utility.
This format allows setting events based on a format similar to crontab, and
adds some extremely useful (but more complicated to understand) features.
Quoting from (and making minor editorial changes to) the Xemacs info node...
A basic diary file looks like this:
4/20/93 Switch-over to new tabulation system
apr. 25 Start tabulating annual results
4/30 Results for April are due
*/25 Monthly cycle finishes
Friday Don't leave without backing up files
The first entry appears only once, on April 20, 1993. The second and third
appear every year on the specified dates, and the fourth uses a wildcard
(asterisk) for the month, so it appears on the 25th of every month. The
final entry appears every week on Friday.
More sophisticated entries allow calling functions (lisp expressions) as
part of the event time. (In all cases, the "European Format" may be
specified so that month and day are swapped; in our application, this would
be irrelevant as the date is stored in the database, not in text format, and
entered via a GUI, not as text):
This entry applies to October 31 in any year after 1948; `10 31 1948'
specifies the date:
%%(diary-anniversary 10 31 1948) Arthur's birthday
A "block" diary entry applies to a specified range of consecutive dates.
Here is a block diary entry that applies to all dates from June 24, 1990
through July 10, 1990:
%%(diary-block 6 24 1990 7 10 1990) Vacation
The `6 24 1990' indicates the starting date and the `7 10 1990' indicates
the stopping date.
"Cyclic" diary entries repeat after a fixed interval of days:
%%(diary-cyclic 50 3 1 1990) Renew medication
This entry applies to March 1, 1990 and every 50th day following; `3 1
1990' specifies the starting date.
Another sophisticated kind of sexp entry, a "floating" diary entry,
specifies a regularly occurring event by offsets specified in days,
weeks, and months. It is comparable to a crontab entry interpreted by
the `cron' utility. Here is a nonmarking, floating diary entry that
applies to the last Thursday in November:
&%%(diary-float 11 4 -1) American Thanksgiving
The 11 specifies November (the eleventh month), the 4 specifies Thursday
(the fourth day of the week, where Sunday is numbered zero), and the -1
specifies "last" (1 would mean "first", 2 would mean "second", -2 would
mean "second-to-last", and so on). The month can be a single month or a
list of months. Thus you could change the 11 above to `'(1 2 3)' and
have the entry apply to the last Thursday of January, February, and
March. If the month is `t', the entry applies to all months of the year.
The generality of lisp sexps (which emacs code is based on) lets you
specify any diary entry that you can describe algorithmically. Suppose
you get paid on the 21st of the month if it is a weekday, and to the
Friday before if the 21st is on a weekend. The diary entry
&%%(let ((dayname (calendar-day-of-week date))
(day (car (cdr date))))
(or (and (= day 21) (memq dayname '(1 2 3 4 5)))
(and (memq day '(19 20)) (= dayname 5)))
) Pay check deposited
to just those dates. This example illustrates how the sexp can depend on
the variable `date'; this variable is a list (MONTH DAY YEAR) that gives
the Gregorian date for which the diary entries are being found. If the
value of the sexp is `t', the entry applies to that date. If the sexp
evaluates to `nil', the entry does _not_ apply to that date.
Cheers,
Derrell
Received on Thu May 16 18:36:56 2002
This archive was generated by hypermail 2.1.8 : Tue May 04 2004 - 09:41:27 EDT