Thursday, April 1, 2010

What date is next Tuesday?

So I was working on a project, and for part of the project, I needed to know what date was the next specific weekday after a given date. Not only that, but the "specific weekday" could be a range of possible weekdays (e.g. "When is the next Monday or Thursday after today?"). After a bit of Googling, I couldn't find a ready-made solution to this, so I decide to take a crack at it.
The following User-Defined Function (since I wanted to make this code reusable) is the fruit of my labor:

CREATE FUNCTION dbo.cust_funct_nextdate 
(@startDate DATETIME, @weekdays VARCHAR(10))
RETURNS DATETIME
AS
BEGIN

DECLARE
@dw INT
,@returndate DATETIME

DECLARE @days TABLE (day_of_week INT)

IF PATINDEX('%U%',@weekdays)
INSERT INTO @days SELECT 1

IF PATINDEX('%M%',@weekdays)
INSERT INTO @days SELECT 2

IF PATINDEX('%T%',@weekdays)
INSERT INTO @days SELECT 3

IF PATINDEX('%W%',@weekdays)
INSERT INTO @days SELECT 4

IF PATINDEX('%R%',@weekdays)
INSERT INTO @days SELECT 5

IF PATINDEX('%F%',@weekdays)
INSERT INTO @days SELECT 6

IF PATINDEX('%S%',@weekdays)
INSERT INTO @days SELECT 7

SET @dw=(
SELECT MIN(day_of_week)
FROM @days
WHERE day_of_week>DATEPART(DW,@startDate))

IF (@dw IS NULL)
SET @returndate=(
SELECT DATEADD(dd,7-(datepart(DW,@startDate)
-(SELECT MIN(day_of_week) FROM @days))
,@startdate))
ELSE
SET @returndate=(
SELECT DATEADD(dd,(
SELECT @dw-DATEPART(dw,@startDate))
,@startDate))

RETURN @returndate
END


As you can see, you pass it a date and a string field containing the letters representing the days of the week you want it to evaluate, following a simple "MTWRFSU" format for Monday through Sunday. It then evaluates the string value to determine what days of the week you want it to look for, and then manipulates the date input to be the next upcoming value in your supplied list of weekdays.

Just a handy tool I thought I'd share for anyone who needs it

1 comment:

  1. David,
    I tried to load create this function as is directly from your code, and got "non-boolean expression" errors for each PATINDEX statement. I had to add a " <> 0" to the end of each PATINDEX condition to get it to work. Did your original code posting omit those by accident, or did I miss something?

    ReplyDelete