## A Specification For Repeating Events

From: andrew cooke <andrew@...>

Date: Thu, 5 Jul 2018 16:21:50 -0400

Introduction

Calendars need to specify repeating events - things like "the second
Tuesday in every month".  I give a way to specify these, with a simple
text format, and also consider some efficiency issues.

Frames and Locations

Repeating events usually consist of a repeating frame and some
location within that frame.  For example, in "the second Tuesday in
every month", the repeating frame is the month and the location is the
second Tuesday.

Frames may repeat with spacing.  For example, "the second Tuesday in
alternate months".  And there may be multiple locations.  For example
"the first Monday and second Tuesday in ...".

Granularity

I am only considering day / week / month repetition, but I think
things should extend to finer granularities if needed.

Date Formats and Timezones

I am ignoring timezones (because of the granularity), but if needed a
timezone code could be appended to the following formats.

Calendar dates are ISO format: YYYY-MM-DD.

It is useful to define ordinals for days, weeks and months.  I base
these on the Unix epoch, so day 0 is 1970-01-01, week 0 is the week
(Mon-Sun) that includes that, month 0 is Jan 1970.  To identify the
frame type, when necessary, I use d/w/m.  So 10d is 1970-01-11, 1m is
Feb 1970, etc.

To label days of the week I use the first two letters of the English
name (Mo, Tu etc).  Code should be case agnostic.

Frame Specification

The specification has the form:

Offset / Repetition FrameType

where offset can be a general data or epoch ordinal that includes a
typical frame or (in the normalized case) the reduced epoch ordinal
(modulo the repetition).  The repetition (bot not the frame type) can
be omitted if 1 and "Offset /" can be omitted if the offset is zero.

So, for example,

1970-02-01/3m  is a monthly frame that repeats every three months
and includes Feb 1970.

1/3m  is the normalized form for the above.

More examples:

d  is a frame that repeats every day.

1/2d  is a frame for alternate days, starting on 1970-01-02

Nested Frames

At this point a design decision is necessary.  How do we identify
weekdays within a month?  This could be handled with nested frames,
which locate a week within the month, and which could be extended to
locating months within years if the framework had years as frames.

use a special syntax for this case (see below) [also, "the second
sunday in the month" is more common, and not identical to, "the sunday
in the second week of the month"].

Location Specification

These are grouped in square brackets, comma-separated.

Days of the month or week (1-7) are numbered.  So [15] is the 15th day
of the month (also, remember that weeks start on Mondays).

Days of the week can also be named, with an ordinal prefix (optional
for first).  So [1Mo] or [Mo] is the first Monday, [2Mo,3Tu] is second
Monday and third Tuesday.  This is the special syntax mentioned
earlier.

Locations outside the frame are ignored (this may be an error or an
expected dependency on context - the 31st day, for example).

A missing location is equivalent to [1] (this is mainly useful for
days).

Range Constraints

A specification may only apply for a certain range of dates.  This is
specified as two dates (ISO format) separated by a dash.  Either date
is optional (indicating open ranges) and the dash may be omitted when
no dates are present.

Both dates are inclusive.  If a single date and no dash is given, then
the event is for a single day.

Complete Specification

Combining the above in order, here are some examples:

m[2Tu]  second Tuesday in every month

2m[2Tu]  second Tuesday in alternate months (Jan, Mar, ...)

1/2m[2Tu]  second Tuesday in alternate months (Feb, Apr, ...)

m[2Tu]1970-01-01-1970-12-31  second Tuesday of each month in 1970

0/1m[2Tu]1970-01-01-1970-12-31  second Tuesday of each month in 1970

2018-07-05/5d[1]  every fifth day, including 2018-07-05

2018-07-05/5d  every fifth day, including 2018-07-05

d2018-07-05  the day of 2018-07-05 (only)

Efficiency

In the normalized form the specification exposes information that
allows many candidates to be discarded:

* Specifications with a date range that exclude the date of
interest.

* Specifications with a reduced offset that does not match the date
of interest.

* Locations that do not match the day of interest.

In addition, it appears that an implementation that expands
specifications to dates should be relatively efficient providing there
is an efficient method to calculate epoch ordinals (which must surely
be possible).

Andrew

* Allowed [1] to be omitted and a single date as range.