Try this on for size.
You have three tables (and possibly a table that holds calculated events.)
PatternTable
-PatternID
-RepeatFrequency (1 daily, 2 weekly, 3 monthly)
-RepeatMultiplier (1 - infinity) This allows for daily, every 3 days. Or Monthly every 3 months.
-Base Day (-7 to 32) negatives are the day of the week (sat = -7, sun = -1) and positives are day of the month. 0 starts with the start date of the event. 32 starts the last day of the month.
-Offset (integer) number of days between the base day and the event (see example for day of week offset)
-resetUnit (null - never, 1 - daily, 2 - weekly , 3 - monthly, 4 - annual) When the reset frequency has been reached, restart at the Next base day.
-reset frequency (null, 1-inifinity) how many reset units before a reset is triggered.
Offset Exmples:
if baseDay is a negative (day of week) then 0 is the week of the event start date. -1 is the last <day of week> in the month. 1 is the first <day of week> in the month.
if baseDay is a positive (day of month) then offset is days + or - from that day of the month.
Example patterns:
Meeting every 3 days starting on the event start date
ID, 1, 3, 0, 0, null, null
Meeting every 5 days starting the first of the month
ID, 1, 5, 1, 0, null, null
One week before the end of each month
ID, 3, 1, 32, -7, null, null
The last Friday of each quarter
ID, 3, 3, -6, -1, null, null
Every 5 mondays in the year starting reset count every year
ID, 2, 5, -5, 0, 4, 1
Third Monday of each month
ID, 3, 1, -2, 3, null, null
Every 5 days starting on the 1st of the month reset each month (ie 1st, 6th, 11th, 16th, 21st, 26th, 31st)
This is different than every 5 days not reset. The later would loop from Jan 31st to Feb 5th.
ID, 1, 5, 1, 0, 3, 1
EventTable
-EventID
-StartDate
-EndDate
-EventDetails
Event-PatternTable
-EventID
-PatternID
By using the Event-Pattern table, you can set multple patterns for the same event. This would allow for a first and third Friday type pattern by creating a pattern for first, and one for third. Also note, when calculating, you want to ignore days that do not exist. For example, a pattern like this:
ID, 3, 1, -5, 5, null null.
This repeats the 5th friday of the month, every month. If there is no fifth friday in a given month, then that month simply gets skipped over.
If you have any questions, let me know.
Thanks
Tejay