Lately, I have been given the task of creating a report scheduling application. This application has many different options when a report is being send out to a client or employee. The options might be similar to what you know from Microsoft Outlook’s Appointment Recurrence screen (as shown on the left).
In order to find the first, second, third or fourth occurrence of any Day Of Week I created the following private function:
private static DateTime FindTheNthDayOfWeek(int year, int month, int nthOccurrence, DayOfWeek dayOfWeek) { if (month < 1 || month > 12) { throw new ArgumentOutOfRangeException("Invalid month"); } if (nthOccurrence < 0 || nthOccurrence > 5) { throw new ArgumentOutOfRangeException("Invalid nth occurrence"); } var dt = new DateTime(year, month, 1); while (dt.DayOfWeek != dayOfWeek) { dt = dt.AddDays(1); } dt = dt.AddDays((nthOccurrence - 1) * 7); if (dt.Month != month) { throw new ArgumentOutOfRangeException(string.Format("The given month has less than {0} {1}s", nthOccurrence, dayOfWeek)); } return dt; }
Let’s take a deeper look at what we are doing here, so let’s talk agnostics: The first two if-statements simply check if the passed in values are valid months as well as valid occurrence values. We know, that there are no month values smaller than 1 or larger than 12. We also know that there are no occurrences of any DayOfWeek smaller than zero. Every DayOfWeek will be represented in a month. No DayOfWeek will be available more than five times in a month either.
Since we are going to be looping through the current month, we are going to start at the beginning of the month. This is what we are doing in line var dt = new DateTime(year, month, 1);
. We are setting the DateTime object to the first of the month which is being passed into our private function.
In our while-loop we are looping through the month until we find the first occurrence of the desired DayOfWeek (ok, we won’t be looping through the whole month as we should find a DayOfWeek match hopefully within the first seven iterations).
Now, we simply have to add one week (or seven days) for each nth occurrence we are looking for:(nthOccurrence - 1) * 7
. We needed to subtract one occurrence as we have already found the first occurrence using the while loop above.
The last check in our function verifies that we didn’t skip into the next month. This would only occur if you would have selected an nthOccurrence value of 5.
This will take care of your needs to implement a report scheduling functionality similar to what Microsoft Outlook provides. The example above covers to find the next n-Occurrences for any day of the week. The example does not cover to find the last occurence or weekends.
0 Comments