Modulus explanation for Steve Kass formula of finding nth day of week in nth week of month

60 Views Asked by At

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
1

There are 1 best solutions below

3
On

The modulus operator ( % ) performs integer division, and returns the remainder.

If you remember elementary school math.

23 divided by 7

7 goes into 23 three times, with a remainder of 2

23 = ( 7 * 3 ) + 2

The modulus function just returns the remainder after the integer division.


And yes, we expect the expression 3%7 to return 3

The expression 10%7 will also return 3.


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.