数周工作一周没有循环?

时间:2011-06-16 15:47:20

标签: c# algorithm datetime

我需要计算给出结构的总工作天数,说明一周中的哪几天是有效的,并且来自和迄今为止。

我目前的算法是:

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;
    }

我几乎肯定这可以在没有循环的情况下完成,但我似乎无法弄明白。有人可以帮我找到更有效的算法吗?

6 个答案:

答案 0 :(得分:4)

查找From和To日期之间的周数(使用减法和除法)。然后乘以每周工作天数。为最终案例做一些减法(从/到日期是在一周的中间)。

答案 1 :(得分:1)

... hmmmm

创建一个字典,从DayOfWeekint,如果我没记错的话),到bool然后....

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

虽然效率不高!

答案 2 :(得分:1)

看看这个codeproject article,它解释了如何在没有循环的情况下进行操作;)

编辑:以下是它使用的公式:

  
      
  1. 以周为单位计算时间跨度。叫它,W。
  2.   
  3. 从周数中扣除第一周。 W = W-1
  4.   
  5. 将周数乘以每周的工作天数。   叫它,D。
  6.   
  7. 在指定的时间范围内查找假期。叫它,H。
  8.   
  9. 计算第一周的天数。叫它,SD。
  10.   
  11. 计算上周的天数。叫它,ED。
  12.   
  13. 总结所有的日子。 BD = D + SD +ED H。
  14.   

答案 3 :(得分:0)

答案 4 :(得分: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;
}

答案 5 :(得分:0)

您可以使用以下算法:

  • 计算开始周的工作日(最多7次迭代)
  • 计算开始/结束与工作日的多周之间的周数
  • 计算结束周的工作日(最多7次迭代)

该示例使用Time Period Library for .NET

DateDiff
// ----------------------------------------------------------------------
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

用法:

// ----------------------------------------------------------------------
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