2017-04-18 379 views
0

我阅读了一些与C#中的函数有关的问题/答案来计算工作日(星期一至星期五的工作日);有些使用扩展的代码来实现这一点。C#如何计算排除特定日期的工作日(假期)

我有一个超过50,000行的数据表,我需要一个有效的方法来计算这些信息。

+0

需要明确的是 - 你希望找到一个在所有的假期某一年(那么你可以计算那些日子的损失时间),还是你在寻找一个工作年的小时数? – confusedandamused

回答

0
/// <summary> Get working days between two dates (Excluding a list of dates - Holidays) </summary> 
/// <param name="dtmCurrent">Current date time</param> 
/// <param name="dtmFinishDate">Finish date time</param> 
/// <param name="lstExcludedDates">List of dates to exclude (Holidays)</param> 
public static int fwGetWorkingDays(this DateTime dtmCurrent, DateTime dtmFinishDate, List<DateTime> lstExcludedDates) 
{ 
    Func<DateTime, bool> workDay = currentDate => 
      (
       currentDate.DayOfWeek == DayOfWeek.Saturday || 
       currentDate.DayOfWeek == DayOfWeek.Sunday || 
       lstExcludedDates.Exists(evalDate => evalDate.Date.Equals(currentDate.Date)) 
      ); 

    return Enumerable.Range(0, 1 + (dtmFinishDate - dtmCurrent).Days).Count(intDay => workDay(dtmCurrent.AddDays(intDay))); 
} 

我创造了这个扩展,基本上有两个日期,日期的列表中排除(节假日)。 令人惊讶的是,此方法速度非常快,并且具有验证功能,可以在与排除列表进行比较时从DateTime中排除时间。

+0

取决于“工作日”的定义。公众假期不被视为工作日。我做你做过的事情PLUS我为未来几年为软件所服务的特定类型的组织提供每年公共假期的清单。如果您将公共假期检查添加到您的代码中,您将得到一个真实的工作日计算器。花费10分钟在未来几年内以10分表格输入10-12行不是一个很大的负担。 –

1

基于@MiBols回答一个更有效的解决方案将是使用的HashSet<DateTime>代替List<DateTime>其中搜索是那么O(1)

/// <summary> Get working days between two dates (Excluding a list of dates - Holidays) </summary> 
/// <param name="dtmCurrent">Current date time</param> 
/// <param name="dtmFinishDate">Finish date time</param> 
/// <param name="excludedDates">Collection of dates to exclude (Holidays)</param> 
public static int fwGetWorkingDays(this DateTime dtmCurrent, DateTime dtmFinishDate, 
            HashSet<DateTime> excludedDates) 
{ 
    Func<DateTime, bool> workDay = currentDate => (
     currentDate.DayOfWeek == DayOfWeek.Saturday || 
     currentDate.DayOfWeek == DayOfWeek.Sunday || 
     excludedDates.Contains(currentDate.Date)); 

    return Enumerable.Range(0, 1 + (dtmFinishDate - dtmCurrent).Days) 
     .Count(intDay => workDay(dtmCurrent.AddDays(intDay))); 
}