Technical Article

IsWorkday UDF without a table

,

While the other methods for calculating holidays ect use a table to store the holidays, this inline UDF goes the opposite route, by returning 1 if the given date is a weekday that also does not fall on a number of holidays.  Examples shown allow for easy extension to other holidays as deemed necessary.

/*****************************************************************************
* funcIsWorkday - Returns 1 if the specified date is a M-F workday that does
* not fall on any of the following holidays:
*New Years Day, Memorial Day, Independence Day, Labor Day,
*Thanksgiving Day and day after, Christmas even, Christmas
*day after Christmas, New Years Eve
******************************************************************************/CREATE FUNCTION [funcIsWorkday]
(
@dtDate datetime
)
RETURNS int AS  
BEGIN 
DECLARE @inDW int
DECLARE @inMonth int
DECLARE @inDay int
DECLARE @inYear int
DECLARE @dtTemp datetime

SET @inDW = DATEPART(dw,@dtDate)

-- Saturday or Sunday
IF (@inDW = 1 OR @inDW = 7)
RETURN 0

-- New years day
IF (@inMonth = 1 AND @inDay = 1)
RETURN 0

-- Memorial Day
IF (@inMonth = 5)
BEGIN
-- Last Monday in the month of May
SET @dtTemp = CAST(('6/1/' + CAST(@inYear AS varchar)) AS datetime)
SET @dtTemp = CASE(DATEPART(dw,@dtTemp))
WHEN 1 THEN DATEADD(dd,-6,@dtTemp)-- Sunday after
WHEN 2 THEN DATEADD(dd,-7,@dtTemp)-- Monday week after
ELSE DATEADD(dd,2-DATEPART(dw,@dtTemp),@dtTemp)
END

IF (@inDay = DAY(@dtTemp))
RETURN 0
END

-- Independence Day
IF (@inMonth = 7 AND @inDay = 4)
RETURN 0

-- Labor Day
-- First Monday in September
IF (@inMonth = 9)
BEGIN
SET @dtTemp = CAST(('9/1/' + CAST(@inYear AS varchar)) AS datetime)
SET @dtTemp = CASE(DATEPART(dw,@dtTemp))
WHEN 1 THEN DATEADD(dd,1,@dtTemp) -- Before Mondy
WHEN 2 THEN @dtTemp -- First of the month
ELSE DATEADD(dd,(7-DATEPART(dw,@dtTemp)+2),@dtTemp) -- After Monday
END

IF (@inDay = DAY(@dtTemp))
RETURN 0
END


-- Thanksgiving Day or day after
-- Fourth Thursday/Friday in November
IF (@inMonth = 11)
BEGIN
SET @dtTemp = CAST(('11/1/' + CAST(@inYear AS varchar)) AS datetime)

SET @dtTemp = CASE 
WHEN DATEPART(dw,@dtTemp) < 5 THEN
DATEADD(dd,5-DATEPART(dw,@dtTemp)+21,@dtTemp) -- Before thursday
WHEN DATEPART(dw,@dtTemp) = 5 THEN
DATEADD(dd,21,@dtTemp)-- Thursday
ELSE DATEADD(dd,7-DATEPART(dw,@dtTemp)+5+21,@dtTemp)-- After thusday
      END
IF (@inDay = DAY(@dtTemp))
RETURN 0 -- Thanksgiving

IF (@inDay - 1 = DAY(@dtTemp))
RETURN 0 -- Day after
END

-- Christmas eve, xmas, day after, new years eve
IF (@inMonth = 12 AND 
(@inDay = 24 OR @inDay = 25 OR @inDay = 26 OR @inDay = 31))
RETURN 0

-- Must be a workday
RETURN 1
END

Read 937 times
(2 in last 30 days)

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating