I'm using the Steve Kass formula to get the nth day of a week in the nth week of the previous month for a given date. It works great - but I really don't understand what the modulus operand does in the formula. Can someone explain? I've tried to supply some givens below:
declare @svcDate as datetime= '1/6/2017', @myN as tinyint=4, @myD as tinyint=1
declare @ret datetime;
declare @first datetime -- First of the month of interest (no time part)
declare @nth tinyint -- Which of them - 1st, 2nd, etc.
declare @dow tinyint -- Day of week we want - this server is set to - 1 sun, 2 mon, 3 tue, 4 wed, 5 thur, 6 fri, 7 sat
set @first = dateadd(month,-1,datefromparts(year(@svcDate), month(@svcDate), 1)) --first of last month
set @nth = @myN
set @dow = @myD
--Select @first 12/1/2016
set @ret = @first + 7*(@nth-1)
--select @ret 12/22/2016 Thurs
--datepart(weekday,@ret)=5
set @ret= @ret + (7 + @dow - datepart(weekday,@ret))%7
if(@ret IS NULL)
set @ret='1/1/2017';
select @ret
select 3%7 --returns 3
select convert(decimal(18,2),3)/convert(decimal(18,2),7) -- returns 0.42857142857142857142
The modulus operator (
%
) performs integer division, and returns the remainder.If you remember elementary school math.
7 goes into 23 three times, with a remainder of 2
The modulus function just returns the remainder after the integer division.
And yes, we expect the expression
3%7
to return3
The expression
10%7
will also return3
.EDIT
Q: Why is modulus operator used in the formula?
A: It's a shortcut that eliminates a lot of conditional checks that would be required if it wasn't used. (The formula could be performed without the modulus operation, but it's much shorter with it.)
In the formula, the subtraction of
weekday
from@dow
could potentially be a negative number of days.And at the point in the formula, we don't want a negative number of days. We want to move forward a number of days, not backwards.
The shortcut is to add seven days to the result of the subtraction. That guarantees us we won't have a negative number of days. But that addition introduces another problem... if the subtraction resulted in a positive number of days, we'd now have a full week plus that number of days. The modulus division eliminates full weeks, leaves us with an integer in the range 0 to 6, the number of days we want to add to
@first
.We could get the same result without using modulus. To do that, we'd do the subtraction of
weekday
from@dow
. If the result from the subtraction is negative, then add 7.The modulus is just a shortcut. The formula adds 7 in all cases, and then subtracts back out 7 in cases the result is greater than 6.