Add business days to date in SQL without loops

后端 未结 25 2858
无人共我
无人共我 2020-12-02 22:54

I currently have a function in my SQL database that adds a certain amount of business days to a date, e.g. if you enter a date that is a Thursday and add two days, it will r

25条回答
  •  南方客
    南方客 (楼主)
    2020-12-02 23:27

    I'm a little late to this party but I wound up writing my own version of this, because of drawbacks in the other solutions. Specifically this version addresses counting backwards, and starting on weekends.

    There's an ambiguous situation that could arise, if you add zero business days to a weekend date. I've kept the date the same, but you can leave out this check if you always want to force a weekday to be returned.

    CREATE FUNCTION [dbo].[fn_AddBusinessDays]
    (
        @date datetime,
        @businessDays int
    )
    RETURNS datetime
    AS
    BEGIN
        --adjust for weeks first
        declare @weeksToAdd int = @businessDays / 7
        declare @daysToAdd int = @businessDays % 7
    
        --if subtracting days, subtract a week then offset
        if @businessDays < 0 begin
            set @daysToAdd = @businessDays + 5
            set @weeksToAdd = @weeksToAdd - 1
        end
    
        --saturday becomes zero using the modulo operator
        declare @originalDayOfWeek int = datepart(dw, @date) % 7
        declare @newDayOfWeek int = datepart(dw, dateadd(d, @daysToAdd, @date)) % 7
    
        --special case for when beginning date is weekend
        --adding zero on a weekend keeps the same date. you can remove the <> 0 check if you want Sunday + 0 => Monday
        declare @dateOffset int = case
            when @businessDays <> 0 and @originalDayOfWeek = 0 then 2
            when @businessDays <> 0 and @originalDayOfWeek = 1 then 1
            when @businessDays <> 0 and @newDayOfWeek < @originalDayOfWeek then 2
            else 0
        end
    
        -- Return the result of the function
        return dateadd(d, @daysToAdd + @dateOffset, dateadd(ww, @weeksToAdd, @date))
    
    END
    

提交回复
热议问题