With the help of answers on SO, I have created a SQL Server UDF (below) which returns the next working day (weekday), given a date and a number of days to add.
For example, if the date is a Friday and you wnat to add one day, the return value is that of the following Monday.
This relies on assuming that @@DATEFIRST is set to 1 (Monday), because we can’t explicitly set DATEFIRST in a UDF.
My problem is that I’d like to deploy this function on several servers but they have different @@DATEFIRST settings and for maintenance purposes between Production, Test and Dev servers I’d rather just have one function that worked without having to worry which @@DATEFIRST setting is in use. I’ve already spent too long wondering why I was getting different results in different environments!
If the answer is simply “use a Stored Proc” then fair enough.
But if anyone can suggest how to refactor the following to be independent of the DATEFIRST setting then that would be great. The significant line is probably going to be if DatePart(dw, @toDate) not in (6, 7)...
Function definition:
CREATE FUNCTION [dbo].[fn_AddBusinessDays]
(
@fromDate datetime,
@daysToAdd int
)
RETURNS datetime
AS
BEGIN
DECLARE @toDate datetime
DECLARE @daysAdded integer
-- add the days, ignoring weekends (i.e. add working days)
set @daysAdded = 1
set @toDate = @fromDate
while @daysAdded <= @daysToAdd
begin
-- add a day to the to date
set @toDate = DateAdd(day, 1, @toDate)
-- only move on a day if we've hit a week day
if DatePart(dw, @toDate) not in (6, 7)
begin
set @daysAdded = @daysAdded + 1
end
end
RETURN @toDate
END
IF (@@DATEFIRST + DATEPART(DW, @toDate)) % 7 not in (0,1)should work for all possibleDATEFIRSTvalues I think.I’d probably use an Auxilliary Calendar table for this anyway rather than a looping UDF.