What you ask though, is how many weeks are covered by a range, not how many weeks are between two dates.
DATEDIFF
always uses Sunday when calculating week transitions.
This isn't a bug, it's done to ensure the function is deterministic and returns the same value, for every query, no matter the DATEFIRST
setting. From the documentation
Specifying SET DATEFIRST has no effect on DATEDIFF. DATEDIFF always uses Sunday as the first day of the week to ensure the function is deterministic.
One solution would be to calculate the difference between the week numbers of the start and end dates, when the first day is Monday. 1
is added to the difference to take account of the first week as well:
SET DATEFIRST 1;
select 1 +datepart(WEEK,'20170131') - datepart(WEEK,'20170101')
That's a fragile calculation though that breaks if DATEFIRST
changes or if one of the dates is on a different year.
You could use ISO Weeks to get rid of SET DATEFIRST
:
select 1 +datepart(ISO_WEEK,'20170131') - datepart(ISO_WEEK,'20170101')
but that would fail for 2017-01-01
because Sunday is counted as Week 52 of the previous year.
A far better solution though would be to count the distinct week numbers using a Calendar table that contains dates and different week numbers to cover multiple business requirements, eg both normal and ISO Week numbers, or business calendars based on a 4-4-5 calendar.
In this case, you could just count distinct week numbers:
SELECT COUNT(DISTINCT Calendar.IsoWeek )
from Calendar
where date between '20170101' and '20170131'
If the table doesn't have an ISO Week column, you can use DATEPART
:
select count (distinct datepart(ISO_WEEK,date) )
from Calendar
where date between '20170101' and '20170131'