Unfortunately, it wasn't a database situation. It was a way to implement the OpenVMS equivalent of the UNIX cron utility. It was a home-grown system utility program. Part of it was scripted, part was compiled code. I'll share with you what experiences I had with the scheduling algorithm. I don't know if you can implement it this way, but it might help you to clarify your thinking on the issue.
The syntax I used was designe to allow me to specify certain timing limits, then parse out the meta-commands for my script fragments, then split out the fragments that were relevant at a given moment. When the parsing was complete, anything that I didn't filter out represented a due (or overdue, see later) event.
The program kept track of the last time it had run to completion. It iterated over the time interval between the last run and the current run in increments of (in my case) 15 minutes. For each time in the interval, the schedule was tested to determine if the associated event should have occurred. The interval was visited using the rule: (Begin..End] - which means include the end time in the scan but not the beginning time. This is also called "open beginning, closed end" (or vice versa, I can never remember which way that is supposed to be.)
The syntax I supported for a scheduled event (remember, this is a program execution scheduler) was
/EVERY - meaning due every time the scheduler runs, which was 15 minutes in my case.
/HOURLY
minutes, minutes....) - meaning due every hour at the specified minutes past the hour. Since I used 15 minute intervals, the PRACTICAL times in minutes were 00, 15, 30, and 45. Nothing else meant anything.
/DAILY
hrs:minutes, hrs:minutes...) - meaning due every day at the specified times. Same limits on minutes as for HOURLY.
/WEEKLY
wkday:hrs:minutes, wkday:hrs:minutes...) - meaning due once per week on the given day of the week at the specified time. Same limits on minutes as for HOURLY. This is how you would make some weekend only or weekday only.
/MONTHLY
day:hrs:minutes, day:hrs:minutes...) - meaning once per month on the specified day of the month at the specified time. In this context, LAST is counted as a proper synonym for the last day of the month regardless of the current month. Same limits on minutes as for HOURLY.
/YEARLY
month:day:hrs:minutes, month:day:hrs:minutes...) - meaning once per year on the given date at the given time. Again, LAST counts as a day of the month. Same limits on minutes as for HOURLY.
For the parenthetical entries, if there was only one time for an event, then I dropped the requirement for parentheses. Only if you had more than one time in the same sequence did you need the parentheses and comma. Defaults were: For month, JAN. For day, 1. For hour, 0. For minute, 0. Therefore, /YEARLY (with no arguments) was midnight January 1. The rule also said that you had to include colons up to the first argument that WASN'T the default value. So for example, /YEARLY::::30 meant January 1st at half-past midnight. (Defaults for month, day, and hour.) But /YEARLY:::1 meant January 1 at 1:00 AM (because you could omit trailing colons when you wanted the default for that field.)
I also had to specify what to do if the scheduler had been idle for a while due to system down time for maintenance or after a program failure. In this case, it was possible that some of my scheduled events had become overdue.
/TIMING: was my switch option for overdue event specification, giving me three choices:
ONCE = schedule the overdue event immediately, but only run one activation no matter how many events were missed.
EXACT = schedule overdue events ONLY at the indicated times. If the event was missed, it was missed. Tough luck.
MULTIPLE = schedule the overdue event once for each time that it should have been, but wasn't, run.
Just as a side effect of the way this code was written, it was possible to specify impossible times. My parser caught that and kicked it out when it was first specified. So you could not write a date such as /YEARLY:FEB:30
However, other times might or might not exist. The scheduler had to be more lenient in some cases.
For example, /MONTHLY:28 is always valid. /MONTHLY:29 is always valid only in leap years. But because at least SOME months have a 29th in them, I allowed it. Ditto for 30 and 31, since at least some months have those days, too. But /MONTHLY:32 was always illegal. In this context, I had a special rule that said /MONTHLY:LAST, which was implemented by seeing if today + 1 day = the first of next month. If so, then today is the last day of this month. (In Access, you can do this by doing a DATEPART of the result of a DATEADD based on today's date.)
I don't know how much of this will be helpful, but this is the way I made it work for a system that didn't have a time-based event scheduler for repetitive event scheduling. If I gave you the code, it would be highly specific for an OpenVMS environment, so you would have a devil of a time adapting it. Also, there is a small issue of the fact that I also work at a government site. You know how tricky it is to exchange code between agencies even when no national security issues exist.
Good luck, my friend. Have fun with your scheduler.