Introduction
This started as a solution to a QA question, and it got me thinking - it's something people need to do, but "date of birth" is very different to "birthday" - it's likely to be several decades different, and we still need to consider December / January.
Using the code
DECLARE @TODAY INT = datepart(dayofyear, GETDATE())
SELECT DOB
FROM Student
WHERE (CASE WHEN datepart(dayofyear, DOB) < @TODAY
THEN datepart(dayofyear, DOB) + 365
ELSE datepart(dayofyear, DOB) END)
BETWEEN @TODAY and @TODAY + 9
Using the day of year means we can ignore leap years and year end - provided we check for "wrap" by adding the year length onto the day number.
This isn't perfect - in December of a leap year it may miss a day, or spot a day early - but for most circumstances that doesn't matter, as it's a "timely reminder" we are looking for. If you need precision, you just replace the constant 365 with the number of days in this year, which can be worked out by:
DATEPART(dayofyear, DATEADD(day, -1 , DATEFROMPARTS(DATEPART(year, DATEADD(year, 1, GETDATE())), 1, 1)))
But that's kinda messy.
DECLARE @TODAY INT = datepart(dayofyear, GETDATE())
DECLARE @DAYSINYEAR INT = DATEPART(dayofyear, DATEADD(day, -1 , DATEFROMPARTS(DATEPART(year, DATEADD(year, 1, GETDATE())), 1, 1)))
SELECT DOB
FROM Student
WHERE (CASE WHEN datepart(dayofyear, DOB) < @TODAY
THEN datepart(dayofyear, DOB) + @DAYSINYEAR
ELSE datepart(dayofyear, DOB) END)
BETWEEN @TODAY and @TODAY + 9
History
2019-12-27 Original version