
.NET 1.1+Calculate the Number of Business Days in a Range (2)
A common task is to calculate the number of business days that exist within a date range. In most western cultures, these are the days from Monday to Friday and excluding Saturdays and Sundays. The resultant number should also exclude national holidays.
Checking for Invalid Date Ranges
The above code ensures that both the start date and end date are valid for use in the algorithm. However, it does not guarantee that the range itself is valid. It is possible that the start date occurs after the end date, or that the original dates provided to the method both fell within the same weekend. In either case, the range should be considered invalid.
If the range is invalid, we will simply return zero. To include this final validation check, add the following code to the end of the Calculate method. The code checks the date range and returns zero if it is invalid. If it is valid, another private method, which calculates the number of business days in the range, is called.
if (startDate > endDate)
return 0;
else
return CalculateDifference(startDate, endDate, holidays);
Checking if a Holiday is Within the Date Range
The next private method that we will add to the class is used to determine whether a single holiday affects the calculation. This method returns a Boolean result, with true indicating that the holiday is within the date range and does not fall on a weekend.
Add the following method to the BusinessDaysCalculator class:
private bool HolidayInRange(DateTime startDate, DateTime endDate, DateTime holiday)
{
return (holiday.Date >= startDate && holiday <= endDate
&& holiday.DayOfWeek != DayOfWeek.Saturday
&& holiday.DayOfWeek != DayOfWeek.Sunday);
}
Counting the Number of Holidays Within the Date Range
The HolidayInRange method is used repeatedly by another private method. The HolidayCount method determines the total number of holidays that affect the calculation. To do so, the method loops through all of the holidays in the array and adds one to a counter each time that the call to HolidayInRange returns true. There is a limitation to this method. If the same date appears twice or more in the holidays array, it will be counted more than once. This can be corrected by ensuring that the array only ever contains unique values.
private int HolidayCount(DateTime startDate, DateTime endDate, DateTime[] holidays)
{
int holidayCount = 0;
foreach (DateTime holiday in holidays)
{
if (HolidayInRange(startDate, endDate, holiday)) holidayCount++;
}
return holidayCount;
}
If you are using a version of the .NET framework that supports Language-Integrated Query (LINQ), you can replace the code in the HolidayCount method with a LINQ expression. The expression below counts the number of holidays that affect the overall calculation. The use of Distinct also ensures that any duplicated holidays are only counted once.
return (from h in holidays
where HolidayInRange(startDate, endDate, h)
select h).Distinct().Count();
10 January 2010