How many days worked in a week without cycles?

I need to calculate the total number of days worked by this structure, in which the days of the week are indicated, and from and to the present.

My current algorithm is this:

protected int TotalWorkDays(DateTime From, DateTime dtTo,WorkedDays days)
    {
        int Days = 0;
        DayOfWeek DOW;
        for (DateTime curDate = From; curDate.Date <= dtTo.Date; curDate = curDate.AddDays(1))
        {
            DOW = curDate.DayOfWeek;
            if ((DOW == DayOfWeek.Sunday &  days.Sunday) |
                (DOW == DayOfWeek.Monday &  days.Monday) |
                (DOW == DayOfWeek.Tuesday &  days.Tuesday) |
                (DOW == DayOfWeek.Wednesday &  days.Wednesday) |
                (DOW == DayOfWeek.Thursday &  days.Thursday) |
                (DOW == DayOfWeek.Friday &  days.Friday) |
                (DOW == DayOfWeek.Saturday &  days.Saturday)
               )
            {
                Days += 1;
            }
        }
        return Days;
    }

I am pretty sure that this can be done without a loop, but I cannot understand. Can someone help me find a more efficient algorithm?

+3
source share
6 answers

Find the number of weeks between From and To dates (using subtraction and division). Then multiply this by the number of work days per week. Do a few subtractions for the end cases (From / to dates in the middle of the week).

+4
source

hmmm ....

, DayOfWeek (int, ), bool ....

var DaysWorked = (from dayoffset in Enumerable.Range(0, (To - From).TotalDays)
                  where WorkingDays[From.AddDays(dayoffset).DayOfWeek]
                  select dayoffset).Count();

, !

+1

codeproject, , ;)

EDIT: :

  • . , W.
  • . W = W-1
  • . , D.
  • . , H.
  • . , SD.
  • . , ED.
  • . BD = D + SD + ED H.
+1

, . :

  • , .
  • , .
  • , .
  • .
0
var workDays = new DayOfWeek[]{ DayOfWeek.Monday, DayOfWeek.Tuesday};
var days = TotalWorkDays(new DateTime(2005,1,12), new DateTime(2005,3,15), workDays);

protected int TotalWorkDays(DateTime start, DateTime end, DayOfWeek[] workDays)
{
    var weeks = (int)Math.Floor((end - start).TotalDays / 7); 
    var days = weeks * workDays.Length;

    //Calc rest
    var d = start.AddDays(weeks * 7);
    while (d <= end)
    {
        if(workDays.Contains(d.DayOfWeek)) 
            days++;
        d = d.AddDays(1);

    }   
    return days;
}
0

:

  • ( 7 )
  • /
  • ( 7 )

DateDiff .NET

// ----------------------------------------------------------------------
public int CountWorkingDays( DateTime start, DateTime end, IList<DayOfWeek> workingDays )
{
  if ( workingDays.Count == 0 )
  {
    return 0;
  }

  Week startWeek = new Week( start );
  Week endWeek = new Week( end );
  int dayCount = 0;

  // start week
  DateTime currentDay = start.Date;
  while ( currentDay < startWeek.End )
  {
    if ( workingDays.Contains( currentDay.DayOfWeek ) )
    {
      dayCount++;
    }
    currentDay = currentDay.AddDays( 1 );
  }

  // between weeks
  DateDiff inBetweenWeekDiff = new DateDiff( startWeek.End, endWeek.Start );
  dayCount += inBetweenWeekDiff.Weeks * workingDays.Count;

  // end week
  currentDay = endWeek.Start.Date;
  while ( currentDay < end )
  {
    if ( workingDays.Contains( currentDay.DayOfWeek ) )
    {
      dayCount++;
    }
    currentDay = currentDay.AddDays( 1 );
  }

  return dayCount;
} // CountWorkingDays

Using:

// ----------------------------------------------------------------------
public void CountWorkingDaysSample()
{
  DayOfWeek[] workingDays = new [] { DayOfWeek.Monday, DayOfWeek.Tuesday };
  DateTime start = new DateTime( 2011, 3, 1 );
  DateTime end = new DateTime( 2011, 5, 1 );
  Console.WriteLine( "working days: {0}", CountWorkingDays( start, end, workingDays ) );
  // > working days: 19
} // CountWorkingDaysSample
0
source

All Articles