从SQL中的ISO周获取日期
我在SQL中创建了一个函数,用“15W53”这样的格式返回ISO周的正确日期。其中,“W”前面的第一部分是年数,第二部分是周数。返回的日期应返回该日期的周初 因此,例如,15W53应返回12-28-2015,16W01应返回01-04-2016。但是,如果我对以下示例运行此命令,从我读到的有关ISO周的内容中,我会得到错误的结果 我是否错误地创建了解析日期的函数从SQL中的ISO周获取日期,sql,iso,date-parsing,Sql,Iso,Date Parsing,我在SQL中创建了一个函数,用“15W53”这样的格式返回ISO周的正确日期。其中,“W”前面的第一部分是年数,第二部分是周数。返回的日期应返回该日期的周初 因此,例如,15W53应返回12-28-2015,16W01应返回01-04-2016。但是,如果我对以下示例运行此命令,从我读到的有关ISO周的内容中,我会得到错误的结果 我是否错误地创建了解析日期的函数 SET DATEFIRST 1; SELECT dbo.[GetDateFromISOweek]('15W52') AS Corre
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,计算如果一年的第一周应该考虑第一个星期(如果有超过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
我的建议是,每当您需要编写函数来计算日期时,您都应该考虑创建一个日期维度表。这会让你的生活轻松1000%。嘿,肖恩,这是个好主意!谢谢你的链接!输入
18W01
时失败。此返回2018-01-08
,预期结果为2018-01-01