簡體   English   中英

在SQL中從ISO周獲取日期

[英]Get Date from ISO Week in SQL

我在SQL中創建了一個函數,以從“ ISO周”以“ 15W53”之類的格式返回正確的日期。 “ W”之前的第一部分是年份數字,后半部分是星期數字。 返回的日期應返回該日期的一周的開始。

因此,例如15W53應該返回2015年12月28日,而16W01應該返回2016年1月4日。 但是,如果我在下面的示例中運行該程序,從我所了解的有關ISO周的信息中得出的結果是錯誤的。

我是否錯誤地創建了函數以解析日期?

SET DATEFIRST 1; 
SELECT dbo.[GetDateFromISOweek]('15W52') AS Correct, '15W52'  -- Returns: 2015-12-21
SELECT dbo.[GetDateFromISOweek]('15W53') AS Correct, '15W53'  -- Returns: 2015-12-28
SELECT dbo.[GetDateFromISOweek]('16W01') AS Incorrect, '16W01'-- Returns: 2015-12-28
SELECT dbo.[GetDateFromISOweek]('16W02') AS Incorrect, '16W02'-- Returns: 2016-01-04
SELECT dbo.[GetDateFromISOweek]('16W03') AS Incorrect, '16W03'-- Returns: 2016-01-11

功能:

CREATE FUNCTION [dbo].[GetDateFromISOweek] (@Input VARCHAR(10))  
RETURNS DATETIME  
WITH EXECUTE AS CALLER  
AS  
BEGIN  
    DECLARE @YearNum CHAR(4) 
    DECLARE @WeekNum VARCHAR(2)

    SET @YearNum = SUBSTRING(@Input,0,CHARINDEX('W',@Input,0))
    SET @WeekNum = SUBSTRING(@Input,CHARINDEX('W',@Input,0)+1,LEN(@Input))

    RETURN(DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + @YearNum) + (@WeekNum-1), 7));
END; 

更改您的納稅申報單中的-1以計算是否應該將一年的第一周考慮為第一周(如果超過三天)。 像這樣

case when DATEDIFF ( day ,  convert(datetime,'01/01/'+ @YearNum),@FirstDay )>=3 then 1 else 0 end

完整的代碼,包括第一個星期天,可以進行改進,但是可以...

CREATE FUNCTION [dbo].[GetDateFromISOweek] (@Input VARCHAR(10))  
RETURNS DATETIME  
WITH EXECUTE AS CALLER  
AS  
BEGIN  
    DECLARE @YearNum CHAR(4) 
    DECLARE @WeekNum VARCHAR(2)
    declare @FirstDay datetime

    SET @YearNum = cast(SUBSTRING(@Input,0,CHARINDEX('W',@Input,0)) as int)+2000
    SET @WeekNum = SUBSTRING(@Input,CHARINDEX('W',@Input,0)+1,LEN(@Input))
    set @FirstDay=DATEADD(DAY, (@@DATEFIRST - DATEPART(WEEKDAY, DATEADD(YEAR, @YearNum - 1900, 0)) +  (8 - @@DATEFIRST) * 2) % 7, DATEADD(YEAR, @YearNum - 1900, 0))-1

    RETURN(DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + @YearNum) + (@WeekNum-case when DATEDIFF ( day ,  convert(datetime,'01/01/'+ @YearNum),@FirstDay )>=3 then 1 else 0 end), 7));
END; 
go
SET DATEFIRST 1; 
SELECT dbo.[GetDateFromISOweek]('15W52'),'15W52' union
SELECT dbo.[GetDateFromISOweek]('15W53'),'15W53' union
SELECT dbo.[GetDateFromISOweek]('16W01'), '16W01' union
SELECT dbo.[GetDateFromISOweek]('16W02'), '16W02' union
SELECT dbo.[GetDateFromISOweek]('16W03'), '16W03'

結果將是

----------------------- -----
2015-12-21 00:00:00.000 15W52
2015-12-28 00:00:00.000 15W53
2016-01-04 00:00:00.000 16W01
2016-01-11 00:00:00.000 16W02
2016-01-18 00:00:00.000 16W03

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM