Calculate the number of business days between two dates?

后端 未结 30 1195
悲&欢浪女
悲&欢浪女 2020-11-22 14:54

In C#, how can I calculate the number of business (or weekdays) days between two dates?

相关标签:
30条回答
  • 2020-11-22 15:41

    Yet another approach for calculating business days, not considering holidays, but taking into account the time of day returning a fractional amount of days:

    public static double GetBusinessDays(DateTime startD, DateTime endD)
    {
        while (IsWeekend(startD))
            startD = startD.Date.AddDays(1);
    
        while (IsWeekend(endD))
            endD = endD.Date.AddDays(-1);
    
        var bussDays = (endD - startD).TotalDays -
            (2 * ((int)(endD - startD).TotalDays / 7)) -
            (startD.DayOfWeek > endD.DayOfWeek ? 2 : 0);
    
        return bussDays;
    }
    
    public static bool IsWeekend(DateTime d)
    {
        return d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday;
    }
    

    You can fiddle with it here: https://rextester.com/ASHRS53997

    0 讨论(0)
  • 2020-11-22 15:41

    This is a generic solution.

    startdayvalue is day number of start date.

    weekendday_1 is day numner of week end.

    day number - MON - 1, TUE - 2, ... SAT - 6, SUN -7.

    difference is difference between two dates..

    Example : Start Date : 4 April, 2013, End Date : 14 April, 2013

    Difference : 10, startdayvalue : 4, weekendday_1 : 7 (if SUNDAY is a weekend for you.)

    This will give you number of holidays.

    No of business day = (Difference + 1) - holiday1

        if (startdayvalue > weekendday_1)
        {
    
            if (difference > ((7 - startdayvalue) + weekendday_1))
            {
                holiday1 = (difference - ((7 - startdayvalue) + weekendday_1)) / 7;
                holiday1 = holiday1 + 1;
            }
            else
            {
                holiday1 = 0;
            }
        }
        else if (startdayvalue < weekendday_1)
        {
    
            if (difference > (weekendday_1 - startdayvalue))
            {
                holiday1 = (difference - (weekendday_1 - startdayvalue)) / 7;
                holiday1 = holiday1 + 1;
            }
            else if (difference == (weekendday_1 - startdayvalue))
            {
                holiday1 = 1;
            }
            else
            {
                holiday1 = 0;
            }
        }
        else
        {
            holiday1 = difference / 7;
            holiday1 = holiday1 + 1;
        }
    
    0 讨论(0)
  • 2020-11-22 15:42

    Based on the comment marked as answer and patch recommended , as well as -> This version wants to convert the Days to Business-Hours ... Considers Same day hours as well.

     /// <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 hours during the 'span'</returns>
        public static int BusinessHoursUntil(DateTime firstDay, DateTime lastDay, params DateTime[] bankHolidays)
        {
            var original_firstDay = firstDay;
            var original_lastDay = lastDay;
            firstDay = firstDay.Date;
            lastDay = lastDay.Date;
            if (firstDay > lastDay)
                return -1; //// 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 = firstDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)firstDay.DayOfWeek;
                int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (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;
    
            if (bankHolidays != null && bankHolidays.Any())
            {
                // 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;
                }
            }
    
            int total_business_hours = 0;
            if (firstDay.Date == lastDay.Date)
            {//If on the same day, go granular with Hours from the Orginial_*Day values
                total_business_hours = (int)(original_lastDay - original_firstDay).TotalHours;
            }
            else
            {//Convert Business-Days to TotalHours
                total_business_hours = (int)(firstDay.AddDays(businessDays).AddHours(firstDay.Hour) - firstDay).TotalHours;
            }
            return total_business_hours;
        }
    
    0 讨论(0)
  • Define an Extension Method on DateTime like so:

    public static class DateTimeExtensions
    {
        public static bool IsWorkingDay(this DateTime date)
        {
            return date.DayOfWeek != DayOfWeek.Saturday
                && date.DayOfWeek != DayOfWeek.Sunday;
        }
    }
    

    Then, use is within a Where clause to filter a broader list of dates:

    var allDates = GetDates(); // method which returns a list of dates
    
    // filter dates by working day's  
    var countOfWorkDays = allDates
         .Where(day => day.IsWorkingDay())
         .Count() ;
    
    0 讨论(0)
  • 2020-11-22 15:48

    Ok. I think it's time to post the right answer:

    public static double GetBusinessDays(DateTime startD, DateTime endD)
    {
        double calcBusinessDays =
            1 + ((endD - startD).TotalDays * 5 -
            (startD.DayOfWeek - endD.DayOfWeek) * 2) / 7;
    
        if (endD.DayOfWeek == DayOfWeek.Saturday) calcBusinessDays--;
        if (startD.DayOfWeek == DayOfWeek.Sunday) calcBusinessDays--;
    
        return calcBusinessDays;
    }
    

    Original Source:

    http://alecpojidaev.wordpress.com/2009/10/29/work-days-calculation-with-c/

    P.S. Solutions posted above making me sic for some reason.

    0 讨论(0)
  • 2020-11-22 15:48

    I came up with the following solution

    var dateStart = new DateTime(2019,01,10);
    var dateEnd = new DateTime(2019,01,31);
    
    var timeBetween = (dateEnd - dateStart).TotalDays + 1;
    int numberOf7DayWeeks = (int)(timeBetween / 7);
    int numberOfWeekendDays = numberOf7DayWeeks * 2;
    int workingDays =(int)( timeBetween - numberOfWeekendDays);
    
    if(dateStart.DayOfWeek == DayOfWeek.Saturday || dateEnd.DayOfWeek == DayOfWeek.Sunday){
        workingDays -=2;
    }       
    if(dateStart.DayOfWeek == DayOfWeek.Sunday || dateEnd.DayOfWeek == DayOfWeek.Saturday){
        workingDays -=1;
    }
    
    0 讨论(0)
提交回复
热议问题