Reputation: 31
I need to get week numbers for some set of dates. For example, for Jan 2016 it should be something like:
[Week Number]
53 <--- for dates from Jan 1 to Jan 2
1 <--- for dates from Jan 3 to Jan 9
2 <--- for dates from Jan 10 to Jan 16
... <--- etc.
As you see, week should start from Sunday. I've used following function to set start day:
SET DATEFIRST 7
And this one to get week number:
DATEPART(ISOWK, SOME_DATE)
But I've noticed that DATEFIRST
doesn't affect results when ISOWK
being used - week always starts from Monday.
So, what am I doing wrong? Thank you!
UPD:
I've made a function, seems it works good:
CREATE FUNCTION [dbo].[GetWeekNumber]
(
@date as DATETIME,
@offset as INT
)
RETURNS NVARCHAR(100)
BEGIN
DECLARE @weekNumber as int
DECLARE @year as int
SET @date = DATEADD(MINUTE, @offset, @date)
SET @year = DATEPART(year, DATEADD(DAY, 1 - DATEPART(WEEKDAY, @date), CAST(@date AS DATE)))
IF @@DATEFIRST = 7
BEGIN
SET @date = DATEADD(day, 1, @date)
END
SET @weekNumber = DATEPART(ISO_WEEK, @date)
RETURN concat(@year, ', Week ', right('0' + convert(nvarchar, @weekNumber), 2))
END
You need to pass the date and timezone offset (in minutes). And SET DATEFIRST @startDay
before executing this function (1 - Monday, 7 - Sunday). Example:
DECLARE @date as DATETIME
SET @date = '2016-01-03 12:00'
SET DATEFIRST 1
SELECT dbo.GetWeekNumber(@date, 0) -- 2015, Week 53
SET DATEFIRST 7
SELECT dbo.GetWeekNumber(@date, 0) -- 2016, Week 01
Upvotes: 3
Views: 2984
Reputation: 31785
This is by design. According to MSDN:
ISO 8601 includes the ISO week-date system, a numbering system for weeks. Each week is associated with the year in which Thursday occurs. For example, week 1 of 2004 (2004W01) ran from Monday 29 December 2003 to Sunday, 4 January 2004.
So ISOWK
is always based on Thursday, and is not affected by DATEFIRST
.
To get the results you want, just use WEEK
instead of ISOWK
.
UPDATE: Also from MSDN:
January 1 of any year defines the starting number for the week datepart, for example: DATEPART (wk, 'Jan 1, xxxx') = 1, where xxxx is any year.
The only way to get Week #1 to be Jan 3-9 is to use math. Subtract one from the DATEPART(wk...)
value, and if the result is 0, make it 53 (or simply use DATEADD
on your date to subtract a week). There is no simpler way, as by design, the first week of any year will be the week that contains Jan 1.
Upvotes: 5