考虑周末和节假日,添加迄今为止的工作日

2024-05-10

给定一个日期和假期列表,如何将给定的工作日数添加到该日期?对于不考虑假期的较小问题有很多解决方案(例如参见向日期添加天数但不包括周末 https://stackoverflow.com/questions/279296/adding-days-to-a-date-but-excluding-weekends).

编辑:我正在寻找 O(1) 或至少线性(假期数量)的解决方案。

请帮忙 谢谢 康斯坦丁


接近 O(1)(没有初始化时间)

如果你真的想要一个 O(1) 的解决方案,我希望你不要考虑初始化问题。

初始化:

  • 构建可查询范围内作为有效返回值的所有日期的排序列表。 (使用类似于 Rik Garner 答案中的代码)
  • 使用上面列表中的日期构建哈希表,以日期作为键,列表中的索引作为值

初始化代码,您只需要一次,然后缓存结果。

查询/计算

 List<DateTime> validWorkdays = // ;
 Dictionary<DateTime, int> lookupIndexOfValidWorkday = // ;

 DateTime AddWorkdays(DateTime start, int count) {
    var startIndex = lookupIndexOfValidWorkday[start];
    return validWorkDays[startIndex + count];
 }

关于从字典中检索 http://msdn.microsoft.com/en-us/library/9tee9ht2.aspx:

获取或设置此属性的值接近 O(1) 操作。

O(n) 假期数

假设假期列表按从最早到最新的顺序排序。 (工作日公式的学分 https://stackoverflow.com/questions/279296/adding-days-to-a-date-but-excluding-weekends/279370#279370)

DateTime AddBusinessDay(DateTime start, int count, IEnumerable<DateTime> holidays) {
   int daysToAdd = count + ((count/ 5) * 2) + ((((int)start.DayOfWeek + (count % 5)) >= 5) ? 2 : 0);
   var end = start.AddDays(daysToAdd);
   foreach(var dt in holidays) {
     if (dt >= start && dt <= end) {
        end = end.AddDays(1);
        if (end.DayOfWeek == DayOfWeek.Saterday) {
          end = end.AddDays(2);
        }
     }
   }
   return end;
}    

该方法可以进行优化。

创建一个仅计算结果的简单公式非常困难,例如您链接到的问题的答案。因为当您调整假期时,您需要考虑可能属于您范围内的新假期。对于周末,您知道它们之间有固定的间隔。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

考虑周末和节假日,添加迄今为止的工作日 的相关文章

随机推荐