My goal is to obtain the nth weekday of a given month. Parameters are a date from a given month and the nth weekday I'm trying to obtain. It returns the Nth Weekday of the month if it exist and returns DateTime.MinValue
othewise. For my purposes weekdays are M-F.
Is there a more elegant or efficient way to implement this logic? My implementation feels crude, basically a while loop that counts weekdays until it finds the desired date or the end of the month.
public static DateTime getNthWeekdayOfMonth(DateTime date, int nthWeekday)
{
//Valid inputs are greater than 0 but less than 24
if (nthWeekday > 23 || nthWeekday < 1)
return DateTime.MinValue;
//start with 1st day of month from date param
DateTime currentDay = new DateTime(date.Year, date.Month, 1);
int i = 0;
while(i < nthWeekday && currentDay.Month == date.Month)
{
if (currentDay.DayOfWeek != DayOfWeek.Saturday && currentDay.DayOfWeek != DayOfWeek.Sunday)
{
i++;
if(i == nthWeekday)
return currentDay;
}
currentDay = currentDay.AddDays(1);
}
return DateTime.MinValue;
}
Usage
var date1 = getNthWeekdayOfMonth(new DateTime(2015, 8, 11), 22);
//returns DateTime.MinValue
var date2 = getNthWeekdayOfMonth(new DateTime(2015, 8, 11), 21);
//returns 8/31/2015
var date3 = getNthWeekdayOfMonth(new DateTime(2015, 8, 11), 1);
//returns 8/3/2015
DateTime?
and returnnull
instead ofDateTime.MinValue
in the case next weekday does not exist. It seem more pragmatic to me than using the "magic" ofMinValue
. \$\endgroup\$Year
when declaringcurrentDay
. So not just the month is used. I would go as far as to include date's Kind just because. \$\endgroup\$return
at the bottom of the method is for expected values and should benull
. The firstreturn
being used in the guard clause is the perfect place for an exception. \$\endgroup\$