Calculate the number of business days between two dates?

后端 未结 30 1171
悲&欢浪女
悲&欢浪女 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:51
    using System;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                DateTime start = new DateTime(2014, 1, 1);
                DateTime stop = new DateTime(2014, 12, 31);
    
                int totalWorkingDays = GetNumberOfWorkingDays(start, stop);
    
                Console.WriteLine("There are {0} working days.", totalWorkingDays);
            }
    
            private static int GetNumberOfWorkingDays(DateTime start, DateTime stop)
            {
                TimeSpan interval = stop - start;
    
                int totalWeek = interval.Days / 7;
                int totalWorkingDays = 5 * totalWeek;
    
                int remainingDays = interval.Days % 7;
    
    
                for (int i = 0; i <= remainingDays; i++)
                {
                    DayOfWeek test = (DayOfWeek)(((int)start.DayOfWeek + i) % 7);
                    if (test >= DayOfWeek.Monday && test <= DayOfWeek.Friday)
                        totalWorkingDays++;
                }
    
                return totalWorkingDays;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 15:52

    I'll just share my solution. It worked for me, maybe I just don't notice/know that theres a bug. I started by getting the first incomplete week if there's any. a complete week was from sunday for saturday, so if the (int)_now.DayOfWeek was not 0(Sunday), the first week was incomplete.

    I just subtract 1 to first weeks count for the first week's saturday then add it to new count;

    Then I get the last incomplete week, then subtract 1 for it's sunday then add to new count.

    Then finally, the number of complete weeks multiply by 5(weekdays) was added to new count.

    public int RemoveNonWorkingDays(int numberOfDays){
    
                int workingDays = 0;
    
                int firstWeek = 7 - (int)_now.DayOfWeek;
    
                if(firstWeek < 7){
    
                    if(firstWeek > numberOfDays)
                        return numberOfDays;
    
                    workingDays += firstWeek-1;
                    numberOfDays -= firstWeek;
                }
    
    
                int lastWeek = numberOfDays % 7;
    
                if(lastWeek > 0){
    
                    numberOfDays -= lastWeek;
                    workingDays += lastWeek - 1;
    
                }
    
                workingDays += (numberOfDays/7)*5;
    
                return workingDays;
            }
    
    0 讨论(0)
  • 2020-11-22 15:53

    I know this question is already solved, but I thought I could provide a more straightforward-looking answer that may help other visitors in the future.

    Here's my take at it:

    public int GetWorkingDays(DateTime from, DateTime to)
    {
        var dayDifference = (int)to.Subtract(from).TotalDays;
        return Enumerable
            .Range(1, dayDifference)
            .Select(x => from.AddDays(x))
            .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
    }
    

    This was my original submission:

    public int GetWorkingDays(DateTime from, DateTime to)
    {
        var totalDays = 0;
        for (var date = from; date < to; date = date.AddDays(1))
        {
            if (date.DayOfWeek != DayOfWeek.Saturday
                && date.DayOfWeek != DayOfWeek.Sunday)
                totalDays++;
        }
    
        return totalDays;
    }
    
    0 讨论(0)
  • 2020-11-22 15:54

    I was having trouble finding a solid TSQL version of this code. Below is essentially a conversion of the C# code here with addition of the Holiday table which should be used to pre-calculate holidays.

    CREATE TABLE dbo.Holiday
    (
        HolidayDt       DATE NOT NULL,
        Name            NVARCHAR(50) NOT NULL,
        IsWeekday       BIT NOT NULL,
        CONSTRAINT PK_Holiday PRIMARY KEY (HolidayDt)
    )
    GO
    CREATE INDEX IDX_Holiday ON Holiday (HolidayDt, IsWeekday)
    
    GO
    
    CREATE function dbo.GetBusinessDays
    (
         @FirstDay  datetime,
         @LastDay   datetime
    ) 
    RETURNS INT
     AS
    BEGIN
        DECLARE @BusinessDays INT, @FullWeekCount INT 
        SELECT  @FirstDay = CONVERT(DATETIME,CONVERT(DATE,@FirstDay))
            ,   @LastDay = CONVERT(DATETIME,CONVERT(DATE,@LastDay))
    
        IF @FirstDay > @LastDay
            RETURN NULL;
    
        SELECT @BusinessDays = DATEDIFF(DAY, @FirstDay, @LastDay) + 1 
        SELECT @FullWeekCount = @BusinessDays / 7;
    
        -- find out if there are weekends during the time exceedng the full weeks
        IF @BusinessDays > (@FullWeekCount * 7)
        BEGIN
        -- 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
            DECLARE @firstDayOfWeek INT, @lastDayOfWeek INT;
            SELECT @firstDayOfWeek = DATEPART(DW, @FirstDay), @lastDayOfWeek = DATEPART(DW, @LastDay);
    
            IF @lastDayOfWeek < @firstDayOfWeek
                    SELECT @lastDayOfWeek = @lastDayOfWeek + 7;
    
            IF @firstDayOfWeek <= 6 
                BEGIN
                    IF (@lastDayOfWeek >= 7) --Both Saturday and Sunday are in the remaining time interval
                        BEGIN 
                            SELECT @BusinessDays = @BusinessDays - 2
                        END
                    ELSE IF @lastDayOfWeek>=6 --Only Saturday is in the remaining time interval
                        BEGIN
                            SELECT @BusinessDays = @BusinessDays - 1
                        END
    
                END
            ELSE IF @firstDayOfWeek <= 7 AND @lastDayOfWeek >=7 -- Only Sunday is in the remaining time interval
            BEGIN 
                SELECT @BusinessDays = @BusinessDays - 1
            END
        END
    
        -- subtract the weekends during the full weeks in the interval
        DECLARE @Holidays INT;
        SELECT  @Holidays = COUNT(*) 
        FROM    Holiday 
        WHERE   HolidayDt BETWEEN @FirstDay AND @LastDay 
        AND     IsWeekday = CAST(1 AS BIT)
    
        SELECT @BusinessDays = @BusinessDays - (@FullWeekCount + @FullWeekCount) -- - @Holidays
    
        RETURN @BusinessDays
    END
    
    0 讨论(0)
  • 2020-11-22 15:54

    Here is one very simple solution for this problem. We have starting date, end date and "for loop" for encreasing the day and calculating to see if it's a workday or a weekend by converting to string DayOfWeek.

    class Program
    {
        static void Main(string[] args)
        {
            DateTime day = new DateTime();
            Console.Write("Inser your end date (example: 01/30/2015): ");
            DateTime endDate = DateTime.Parse(Console.ReadLine());
            int numberOfDays = 0;
            for (day = DateTime.Now.Date; day.Date < endDate.Date; day = day.Date.AddDays(1))
            {
                string dayToString = Convert.ToString(day.DayOfWeek);
                if (dayToString != "Saturday" && dayToString != "Sunday") numberOfDays++;
            }
            Console.WriteLine("Number of working days (not including local holidays) between two dates is "+numberOfDays);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 15:54

    Here is an helper function I wrote for that task.
    it also returns the count of weekends via the out parameter.
    if you wish you can customize the "weekend" days in run time for countries that use different weekend days or to include holidays trough the weekendDays[] optional parameter :

    public static int GetNetworkDays(DateTime startDate, DateTime endDate,out int totalWeekenDays, DayOfWeek[] weekendDays = null)
    {
        if (startDate >= endDate)
        {
            throw new Exception("start date can not be greater then or equel to end date");
        }
    
        DayOfWeek[] weekends = new DayOfWeek[] { DayOfWeek.Sunday, DayOfWeek.Saturday };
        if (weekendDays != null)
        {
            weekends = weekendDays;
        }
    
        var totaldays = (endDate - startDate).TotalDays + 1; // add one to include the first day to
        var counter = 0;
        var workdaysCounter = 0;
        var weekendsCounter = 0;
    
        for (int i = 0; i < totaldays; i++)
        {
    
            if (weekends.Contains(startDate.AddDays(counter).DayOfWeek))
            {
                weekendsCounter++;
            }
            else
            {
                workdaysCounter++;
            }
    
            counter++;
        }
    
        totalWeekenDays = weekendsCounter;
        return workdaysCounter;
    }
    
    0 讨论(0)
提交回复
热议问题