[英]SQL Server: change first day of week to Sunday using DATEPART with ISOWK parameter
I need to get week numbers for some set of dates. 我需要获得一些日期的周数 。 For example, for Jan 2016 it should be something like:
例如,对于2016年1月,它应该是这样的:
[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. 但我注意到,当使用
ISOWK
时, DATEFIRST
不会影响结果 - 周总是从星期一开始。
So, what am I doing wrong? 那么,我做错了什么? Thank you!
谢谢!
UPD: 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). 并且在执行此功能之前
SET DATEFIRST @startDay
(1 - 星期一,7 - 星期日)。 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
This is by design. 这是设计的。 According to MSDN :
根据MSDN :
ISO 8601 includes the ISO week-date system, a numbering system for weeks.
ISO 8601包括ISO周日期系统,一个数周的编号系统。 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.
例如,2004年第1周(2004W01)从2003年12月29日星期一到2004年1月4日星期日。
So ISOWK
is always based on Thursday, and is not affected by DATEFIRST
. 所以
ISOWK
总是基于星期四,并且不受DATEFIRST
影响。
To get the results you want, just use WEEK
instead of ISOWK
. 要获得所需的结果,只需使用
WEEK
而不是ISOWK
。
UPDATE: Also from MSDN: 更新:也来自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.
任何一年的1月1日定义星期datepart的起始编号,例如:DATEPART(wk,'Jan 1,xxxx')= 1,其中xxxx是任何年份。
The only way to get Week #1 to be Jan 3-9 is to use math. 让第1周成为1月3日至9日的唯一方法是使用数学。 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). 从
DATEPART(wk...)
值中减去1,如果结果为0,则将其设为53(或者在日期中使用DATEADD
减去一周)。 There is no simpler way, as by design, the first week of any year will be the week that contains Jan 1. 没有更简单的方法,因为按设计,任何一年的第一周将是包含1月1日的那一周。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.