Back on topic, I am sure this could have been done much, MUCH better. But since I am really terrible at maths, this is how I avoided loops for calculating the "index" (i.e. the n'th time it happened) of a weekly recurring appointment for a calendar app in javascript:
// Does it occur on target date?
if ((this.pattern.weekdays & p.date.get.dotw(h.target)))
{
// How many week has it been since this appointment started?
var weeksSinceStart = p.date.get.weeksBetween(h.current, h.target);
// Skip this week?
if (weeksSinceStart % this.pattern.periodicity)
{
return null;
}
// How many blind occurrences are there?
// e.g. appointment starts on a WED but the pattern is MO/_WED_/TH/SU = 1 blind (MO)
var blind_occurrences = 0;
// Avoid loop with clever switch
switch ((this.pattern.weekdays & p.date.get.dotw(this.start)))
{
// INTENTIONAL FALL-THROUGHS!!! //
case FLAG_SUNDAY:
(this.pattern.weekdays & FLAG_SATURDAY) && blind_occurrences++;
case FLAG_SATURDAY:
(this.pattern.weekdays & FLAG_FRIDAY) && blind_occurrences++;
case FLAG_FRIDAY:
(this.pattern.weekdays & FLAG_THURSDAY) && blind_occurrences++;
case FLAG_THURSDAY:
(this.pattern.weekdays & FLAG_WEDNESDAY) && blind_occurrences++;
case FLAG_WEDNESDAY:
(this.pattern.weekdays & FLAG_TUESDAY) && blind_occurrences++;
case FLAG_TUESDAY:
(this.pattern.weekdays & FLAG_MONDAY) && blind_occurrences++;
}
// How often has it already occurred *this* week?
var occurrenceIndexThisWeek = -blind_occurrences;
// Avoid loop with clever switch
switch ((this.pattern.weekdays & p.date.get.dotw(h.target)))
{
// INTENTIONAL FALL-THROUGHS!!! //
case FLAG_SUNDAY:
(this.pattern.weekdays & FLAG_SATURDAY) && occurrenceIndexThisWeek++;
case FLAG_SATURDAY:
(this.pattern.weekdays & FLAG_FRIDAY) && occurrenceIndexThisWeek++;
case FLAG_FRIDAY:
(this.pattern.weekdays & FLAG_THURSDAY) && occurrenceIndexThisWeek++;
case FLAG_THURSDAY:
(this.pattern.weekdays & FLAG_WEDNESDAY) && occurrenceIndexThisWeek++;
case FLAG_WEDNESDAY:
(this.pattern.weekdays & FLAG_TUESDAY) && occurrenceIndexThisWeek++;
case FLAG_TUESDAY:
(this.pattern.weekdays & FLAG_MONDAY) && occurrenceIndexThisWeek++;
}
// Set index
var index = (weeksSinceStart * this.occurrencesPerWeek / this.pattern.periodicity) + occurrenceIndexThisWeek;