65.9K
CodeProject is changing. Read more.
Home

Get a list of Dates for the Nth Desired Day of Week in a Month for a range of dates

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.70/5 (3 votes)

Feb 23, 2016

CPOL
viewsIcon

9895

A C# method that will return a list of DateTime for a given week of the month (1st to 5th (5th week meaning days 29-31, where they exist in a given month)) and Day of Week over a span of time

Eschatological Emanations

In case you want a list of dates (not just one) for a span of time for the Nth DayOfWeek of a Month (such as the first Monday of every month for the next year), you can use this method:

internal static List GetDatesForNthDOWOfMonth(int weekNum, DayOfWeek DOW, DateTime beginDate, DateTime endDate)
{
    List<DateTime> datesForNthDOWOfMonth = new List<DateTime>();
    DateTime currentDate = beginDate;
    // thanks to kaos_121
    int earliest = Math.Min(weekNo * 7 - 6, 29);
    int latest = Math.Min(weekNo * 7, 31);

    while (currentDate < endDate)
    {
        DateTime dateToInc = currentDate;
        DateTime endOfMonth = new DateTime(dateToInc.Year, dateToInc.Month, DateTime.DaysInMonth(dateToInc.Year, dateToInc.Month));
        bool dateFound = false;
        while (!dateFound)
        {
            dateFound = dateToInc.DayOfWeek.Equals(DOW);
            if (dateFound)
            {
                if ((dateToInc.Day >= earliestDayOfMonth) && 
                    (dateToInc.Day <= latestDayOfMonth))
                {
                    datesForNthDOWOfMonth.Add(dateToInc);
                }
            }
            if (dateToInc.Date.Equals(endOfMonth.Date)) continue;
            dateToInc = dateToInc.AddDays(1);
        }
        currentDate = new DateTime(currentDate.Year, currentDate.Month, 1);
        currentDate = currentDate.AddMonths(1);
    }
    return datesForNthDOWOfMonth;
}

...and call it this way:

// This is to get the 1st Monday in each month from today through one year from today
DateTime beg = DateTime.Now;
DateTime end = DateTime.Now.AddYears(1);
List<DateTime> dates = GetDatesForNthDOWOfMonth(1, DayOfWeek.Monday, beg, end);
// To see the list of dateTimes, for verification
foreach (DateTime dt in dates)
{
    MessageBox.Show(string.Format("Found {0}", dt.ToString()));
}

You could get the 2nd Friday of each month like so:

List<DateTime> dates = GetDatesForNthDOWOfMonth(2, DayOfWeek.Friday, beg, end);

...etc.