Counting regular working days in a given period of time

后端 未结 8 422
庸人自扰
庸人自扰 2021-01-12 05:38

need some help. I need to count regular working days for a given date period, for example, in our country, we have 5 regular working days monday to friday, then in code i ne

相关标签:
8条回答
  • 2021-01-12 05:48

    Not very fast, but this will do the trick:

    int GetRegularWorkingDays(DateTime start, DateTime end)
    {
        return (
            from day in Range(start, end)
            where day.DayOfWeek != DayOfWeek.Saturday
            where day.DayOfWeek != DayOfWeek.Sunday
            select day).Count();
    }
    
    IEnumerable<DateTime> Range(DateTime start, DateTime end)
    {
        while (start <= end)
        {
            yield return start;
            start = start.AddDays(1);
        }
    }
    
    0 讨论(0)
  • 2021-01-12 05:53

    One-liner!

    int workingDays = Enumerable.Range(0, Convert.ToInt32(endDate.Subtract(startDate).TotalDays)).Select(i=>new [] { DayOfWeek.Saturday, DayOfWeek.Sunday }.Contains(startDate.AddDays(i).DayOfWeek) ? 0 : 1).Sum();
    

    Or more efficient:

    DayOfWeek currDay = startDate.DayOfWeek;
    int nonWorkingDays = 0;
    
    foreach(var i in Enumerable.Range(0, Convert.ToInt32(endDate.Subtract(startDate).TotalDays)))
    {
         if(currDay == DayOfWeek.Sunday || currDay == DayOfWeek.Saturday) 
              nonWorkingDays++;
         if((int)++currDay > 6) currDay = (DayOfWeek)0;
    }
    
    0 讨论(0)
  • 2021-01-12 05:59

    You could do it with a time line helper class - this class also allows for other intervals:

    public class TimeLine
    {
        public static IEnumerable<DateTime> CreateTimeLine(DateTime start, TimeSpan interval) {
            return TimeLine.CreateTimeLine(start, interval, DateTime.MaxValue);
        }
    
        public static IEnumerable<DateTime> CreateTimeLine(DateTime start, TimeSpan interval, DateTime end) {
            var currentVal = start;
            var endVal = end.Subtract(interval);
    
            do {
                currentVal = currentVal.Add(interval);
                yield return currentVal;
            } while (currentVal <= endVal);
        }
    }
    

    To solve your problem you can do the following:

    var workingDays = TimeLine.CreateTimeLine(DateTime.Now.Date, TimeSpan.FromDays(1), DateTime.Now.Date.AddDays(30))
                              .Where(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
    var noOfWorkingDays = workingDays.Count();
    

    This time line class can be used for any continuous time line of any interval.

    0 讨论(0)
  • 2021-01-12 06:01

    Simple method to get work days:

    int GetRegularWorkingDays(DateTime startDate, DateTime endDate)
    {
        int total = 0;
    
        if (startDate < endDate)
        {
            var days = endDate - startDate;
    
            for( ; startDate < endDate; startDate = startDate.AddDays(1) )
            {
                switch(startDate.DayOfWeek)
                {
                    case DayOfWeek.Saturday :
                    case DayOfWeek.Sunday :                     
                        break;
                    default:
                        total++;
                        break;
                }
            }
        }
        return total;
    }
    
    0 讨论(0)
  • 2021-01-12 06:07

    You could try a simple method of just counting the days. If this is usually done for periods of time like months and not years and isn't called repeatedly then this will not be a performance hit to just walk it.

    int GetWorkingDays(DateTime startDate, DateTime endDate)
    {
        int count = 0;
        for (DateTime currentDate = startDate; currentDate < endDate; currentDate = currentDate.AddDays(1))
        {
            if (currentDate.DayOfWeek == DayOfWeek.Sunday || currentDate.DayOfWeek == DayOfWeek.Saturday)
            {
                continue;
            }
            count++;
        }
        return count;
    }
    
    0 讨论(0)
  • 2021-01-12 06:11

    I wrote a type extender to allow me to add (or subtract) weekdays to a given date. Maybe this will help you. Works great, so please vote for my post if this helped you.

        /// <summary>
        /// Adds weekdays to date
        /// </summary>
        /// <param name="value">DateTime to add to</param>
        /// <param name="weekdays">Number of weekdays to add</param>
        /// <returns>DateTime</returns>
        public static DateTime AddWeekdays(this DateTime value, int weekdays)
        {
            int direction = Math.Sign(weekdays);
            int initialDayOfWeek = Convert.ToInt32(value.DayOfWeek);
    
            //---------------------------------------------------------------------------
            // if the day is a weekend, shift to the next weekday before calculating
            if ((value.DayOfWeek == DayOfWeek.Sunday && direction < 0)
                || (value.DayOfWeek == DayOfWeek.Saturday && direction > 0))
            {
                value = value.AddDays(direction * 2);
                weekdays += (direction * -1); // adjust days to add by one
            }
            else if ((value.DayOfWeek == DayOfWeek.Sunday && direction > 0)
                || (value.DayOfWeek == DayOfWeek.Saturday && direction < 0))
            {
                value = value.AddDays(direction);
                weekdays += (direction * -1); // adjust days to add by one
            }
            //---------------------------------------------------------------------------
    
            int weeksBase = Math.Abs(weekdays / 5);
            int addDays = Math.Abs(weekdays % 5);
    
            int totalDays = (weeksBase * 7) + addDays;
            DateTime result = value.AddDays(totalDays * direction);
    
            //---------------------------------------------------------------------------
            // if the result is a weekend, shift to the next weekday
            if ((result.DayOfWeek == DayOfWeek.Sunday && direction > 0)
                || (result.DayOfWeek == DayOfWeek.Saturday && direction < 0))
            {
                result = result.AddDays(direction);
            }
            else if ((result.DayOfWeek == DayOfWeek.Sunday && direction < 0)
                || (result.DayOfWeek == DayOfWeek.Saturday && direction > 0))
            {
                result = result.AddDays(direction * 2);
            }
            //---------------------------------------------------------------------------
    
            return result;
        }
    
    0 讨论(0)
提交回复
热议问题