Calculate the number of business days between two dates?

后端 未结 30 1666
悲&欢浪女
悲&欢浪女 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:50

    I searched a lot for a, easy to digest, algorithm to calculate the working days between 2 dates, and also to exclude the national holidays, and finally I decide to go with this approach:

    public static int NumberOfWorkingDaysBetween2Dates(DateTime start,DateTime due,IEnumerable holidays)
            {
                var dic = new Dictionary();
                var totalDays = (due - start).Days;
                for (int i = 0; i < totalDays + 1; i++)
                {
                    if (!holidays.Any(x => x == start.AddDays(i)))
                        dic.Add(start.AddDays(i), start.AddDays(i).DayOfWeek);
                }
    
                return dic.Where(x => x.Value != DayOfWeek.Saturday && x.Value != DayOfWeek.Sunday).Count();
            } 
    

    Basically I wanted to go with each date and evaluate my conditions:

    1. Is not Saturday
    2. Is not Sunday
    3. Is not national holiday

    but also I wanted to avoid iterating dates.

    By running and measuring the time need it to evaluate 1 full year, I go the following result:

    static void Main(string[] args)
            {
                var start = new DateTime(2017, 1, 1);
                var due = new DateTime(2017, 12, 31);
    
                var sw = Stopwatch.StartNew();
                var days = NumberOfWorkingDaysBetween2Dates(start, due,NationalHolidays());
                sw.Stop();
    
                Console.WriteLine($"Total working days = {days} --- time: {sw.Elapsed}");
                Console.ReadLine();
    
                // result is:
               // Total working days = 249-- - time: 00:00:00.0269087
            }
    

    Edit: a new method more simple:

    public static int ToBusinessWorkingDays(this DateTime start, DateTime due, DateTime[] holidays)
            {
                return Enumerable.Range(0, (due - start).Days)
                                .Select(a => start.AddDays(a))
                                .Where(a => a.DayOfWeek != DayOfWeek.Sunday)
                                .Where(a => a.DayOfWeek != DayOfWeek.Saturday)
                                .Count(a => !holidays.Any(x => x == a));
    
            }
    

提交回复
热议问题