一尘不染

计算两个日期之间的工作日数?

c#

在C#中,如何计算两个日期之间的 营业 (或工作日)天数?


阅读 368

收藏
2020-05-19

共1个答案

一尘不染

我之前有过这样的任务,并且已经找到了解决方案。在这种情况下,我会避免列举所有两天之间可避免的情况。正如我在上面的答案之一中所看到的,我什至没有提到创建一堆DateTime实例。这确实是在浪费处理能力。特别是在现实世界中,当您必须检查几个月的时间间隔时。请在下面查看我的代码及其注释。

    /// <summary>
    /// Calculates number of business days, taking into account:
    ///  - weekends (Saturdays and Sundays)
    ///  - bank holidays in the middle of the week
    /// </summary>
    /// <param name="firstDay">First day in the time interval</param>
    /// <param name="lastDay">Last day in the time interval</param>
    /// <param name="bankHolidays">List of bank holidays excluding weekends</param>
    /// <returns>Number of business days during the 'span'</returns>
    public static int BusinessDaysUntil(this DateTime firstDay, DateTime lastDay, params DateTime[] bankHolidays)
    {
        firstDay = firstDay.Date;
        lastDay = lastDay.Date;
        if (firstDay > lastDay)
            throw new ArgumentException("Incorrect last day " + lastDay);

        TimeSpan span = lastDay - firstDay;
        int businessDays = span.Days + 1;
        int fullWeekCount = businessDays / 7;
        // find out if there are weekends during the time exceedng the full weeks
        if (businessDays > fullWeekCount*7)
        {
            // we are here to find out if there is a 1-day or 2-days weekend
            // in the time interval remaining after subtracting the complete weeks
            int firstDayOfWeek = (int) firstDay.DayOfWeek;
            int lastDayOfWeek = (int) lastDay.DayOfWeek;
            if (lastDayOfWeek < firstDayOfWeek)
                lastDayOfWeek += 7;
            if (firstDayOfWeek <= 6)
            {
                if (lastDayOfWeek >= 7)// Both Saturday and Sunday are in the remaining time interval
                    businessDays -= 2;
                else if (lastDayOfWeek >= 6)// Only Saturday is in the remaining time interval
                    businessDays -= 1;
            }
            else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)// Only Sunday is in the remaining time interval
                businessDays -= 1;
        }

        // subtract the weekends during the full weeks in the interval
        businessDays -= fullWeekCount + fullWeekCount;

        // subtract the number of bank holidays during the time interval
        foreach (DateTime bankHoliday in bankHolidays)
        {
            DateTime bh = bankHoliday.Date;
            if (firstDay <= bh && bh <= lastDay)
                --businessDays;
        }

        return businessDays;
    }

Slauma编辑,2011年8月

好答案!虽然没有什么bug。自2009年以来就没有应答者,因此我可以自由地编辑此答案。

上面的代码假定DayOfWeek.Sunday该值7不是这种情况。该值实际上是0。例如firstDay,如果lastDay两个星期天都相同,则会导致错误的计算。1在这种情况下,该方法返回,但应该为0

此错误的最简单修复:在以下代码中声明firstDayOfWeek和的行上方的代码中替换lastDayOfWeek以下内容:

int firstDayOfWeek = firstDay.DayOfWeek == DayOfWeek.Sunday 
    ? 7 : (int)firstDay.DayOfWeek;
int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday
    ? 7 : (int)lastDay.DayOfWeek;

现在的结果是:

  • 周五至周五-> 1
  • 周六至周六-> 0
  • 周日至周日-> 0
  • 周五至周六-> 1
  • 周五至周日-> 1
  • 星期五至星期一-> 2
  • 周六至周一-> 1
  • 周日至周一-> 1
  • 周一至周一-> 1
2020-05-19