代码之家  ›  专栏  ›  技术社区  ›  InvaderZim

从SQL中的ISO周获取日期

  •  1
  • InvaderZim  · 技术社区  · 7 年前

    例如,15W53应返回12-28-2015,16W01应返回01-04-2016。然而,如果我为下面的例子运行这个,从我读到的关于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 回复  |  直到 7 年前
        1
  •  2
  •   Fabricio    7 年前

    将报税表中的-1改为计算一年中的第一周是否应考虑第一周(如果有3天以上)。

    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