Counting regular working days in a given period of time

Check out this example on Code Project that uses a very efficient way that doesn't involve any looping ;)

It uses this alogrithm:

  1. Calculate the number of time span in terms of weeks. Call it, W.
  2. Deduct the first week from the number of weeks. W= W-1
  3. Multiply the number of weeks with the number of working days per week. Call it, D.
  4. Find out the holidays during the specified time span. Call it, H.
  5. Calculate the days in the first week. Call it, SD.
  6. Calculate the days in the last week. Call it, ED.
  7. Sum up all the days. BD = D + SD + ED - H.

One-liner!

int workingDays = Enumerable.Range(0, Convert.ToInt32(endDate.Subtract(startDate).TotalDays)).Select(i=>new [] { DayOfWeek.Saturday, DayOfWeek.Sunday }.Contains(startDate.AddDays(i).DayOfWeek) ? 0 : 1).Sum();

Or more efficient:

DayOfWeek currDay = startDate.DayOfWeek;
int nonWorkingDays = 0;

foreach(var i in Enumerable.Range(0, Convert.ToInt32(endDate.Subtract(startDate).TotalDays)))
{
     if(currDay == DayOfWeek.Sunday || currDay == DayOfWeek.Saturday) 
          nonWorkingDays++;
     if((int)++currDay > 6) currDay = (DayOfWeek)0;
}

I wrote a type extender to allow me to add (or subtract) weekdays to a given date. Maybe this will help you. Works great, so please vote for my post if this helped you.

    /// <summary>
    /// Adds weekdays to date
    /// </summary>
    /// <param name="value">DateTime to add to</param>
    /// <param name="weekdays">Number of weekdays to add</param>
    /// <returns>DateTime</returns>
    public static DateTime AddWeekdays(this DateTime value, int weekdays)
    {
        int direction = Math.Sign(weekdays);
        int initialDayOfWeek = Convert.ToInt32(value.DayOfWeek);

        //---------------------------------------------------------------------------
        // if the day is a weekend, shift to the next weekday before calculating
        if ((value.DayOfWeek == DayOfWeek.Sunday && direction < 0)
            || (value.DayOfWeek == DayOfWeek.Saturday && direction > 0))
        {
            value = value.AddDays(direction * 2);
            weekdays += (direction * -1); // adjust days to add by one
        }
        else if ((value.DayOfWeek == DayOfWeek.Sunday && direction > 0)
            || (value.DayOfWeek == DayOfWeek.Saturday && direction < 0))
        {
            value = value.AddDays(direction);
            weekdays += (direction * -1); // adjust days to add by one
        }
        //---------------------------------------------------------------------------

        int weeksBase = Math.Abs(weekdays / 5);
        int addDays = Math.Abs(weekdays % 5);

        int totalDays = (weeksBase * 7) + addDays;
        DateTime result = value.AddDays(totalDays * direction);

        //---------------------------------------------------------------------------
        // if the result is a weekend, shift to the next weekday
        if ((result.DayOfWeek == DayOfWeek.Sunday && direction > 0)
            || (result.DayOfWeek == DayOfWeek.Saturday && direction < 0))
        {
            result = result.AddDays(direction);
        }
        else if ((result.DayOfWeek == DayOfWeek.Sunday && direction < 0)
            || (result.DayOfWeek == DayOfWeek.Saturday && direction > 0))
        {
            result = result.AddDays(direction * 2);
        }
        //---------------------------------------------------------------------------

        return result;
    }