我需要获取某些日期集的 周数 。例如,对于 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.
如您所见,一周应该从星期日开始。我使用以下函数来设置开始日期:
SET DATEFIRST 7
而这个获得周数:
DATEPART(ISOWK, SOME_DATE)
但是我注意到
DATEFIRST
在使用 ISOWK
时不会影响结果 - 周总是从星期一开始。那么,我做错了什么?谢谢!
UPD:
我做了一个函数,看起来效果很好:
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
您需要传递日期和时区偏移量(以分钟为单位)。和
SET DATEFIRST @startDay
在执行此函数之前(1 - 星期一,7 - 星期日)。例子: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
最佳答案
这是设计使然。根据 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.
所以
ISOWK
总是基于星期四,并且不受 DATEFIRST
的影响。要获得您想要的结果,只需使用
WEEK
而不是 ISOWK
。更新:同样来自 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 月 3 日至 9 日举行的唯一方法是使用数学。从
DATEPART(wk...)
值中减去一个,如果结果为 0,则将其设为 53(或者简单地在您的日期使用 DATEADD
减去一周)。没有更简单的方法,因为按照设计,任何一年的第一周都是包含 1 月 1 日的那一周。
关于SQL Server : change first day of week to Sunday using DATEPART with ISOWK parameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36340144/