简体   繁体   English

SQL Server:使用带有ISOWK参数的DATEPART将周的第一天更改为星期日

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM