Full disclosure, I attempted to convert from this function I wrote 10 years ago, but am getting the math wrong now. - I'm pretty sure each part in this script works, I'm just not applying the new variables correctly.CREATE FUNCTION [dbo].[udfConvertFromGMT]
(
@InputDate DATETIME
)
RETURNS DATETIME
AS
/*
Script Date: 08/11/2009
Author: Sean Senneka
Purpose: Converts from GMT to CST (or CDT if date is during daylight savings time)
*/
--DECLARE @InputDate datetime
--Select @InputDate = '10/4/1985 08:00:00'
BEGIN
DECLARE @converted_date DATETIME;
DECLARE @DST_Start DATETIME;
DECLARE @DST_End DATETIME;
DECLARE @GMT_Offset_Destination INT;
-- Get start and end dates for daylight savingstime for the year in question
SELECT @DST_Start = CASE
WHEN DATEPART(YEAR, @InputDate) >= 2007 THEN
'3/1/' + CONVERT(VARCHAR, DATEPART(YEAR, @InputDate))
WHEN DATEPART(YEAR, @InputDate)
BETWEEN 1986 AND 2006 THEN
'4/1/' + CONVERT(VARCHAR, DATEPART(YEAR, @InputDate))
ELSE -- Year prior to 1986
'4/30/' + CONVERT(VARCHAR, DATEPART(YEAR, @InputDate))
END,
@DST_End = CASE
WHEN DATEPART(YEAR, @InputDate) >= 2007 THEN
'11/1/' + CONVERT(VARCHAR, DATEPART(YEAR, @InputDate))
ELSE
'10/31/' + CONVERT(VARCHAR, DATEPART(YEAR, @InputDate))
END;
SELECT @DST_Start
=
--2007 till present get second Sunday of March, 1986-2006 get first Sunday of April, prior to 1986 get last sunday in April
CASE
WHEN DATEPART(YEAR, @InputDate) >= 2007 THEN
DATEADD(
HOUR,
8,
DATEADD(
DAY,
((CEILING((CAST(17 AS DECIMAL(8, 2)) % DATEPART(dw, @DST_Start)) / 10) * 7) + 8)
- DATEPART(dw, @DST_Start),
@DST_Start
)
)
WHEN DATEPART(YEAR, @InputDate)
BETWEEN 1986 AND 2006 THEN
DATEADD(
HOUR,
8,
DATEADD(
DAY,
((CEILING((CAST(17 AS DECIMAL(8, 2)) % DATEPART(dw, @DST_Start)) / 10) * 7) + 1)
- DATEPART(dw, @DST_Start),
@DST_Start
)
)
ELSE -- Year prior to 1986
DATEADD(HOUR, 8, DATEADD(DAY, 0 - (DATEPART(dw, @DST_Start) - 1), @DST_Start))
END,
--2007 till present get first Sunday of November, else get last Sunday of October
@DST_End
= CASE
WHEN DATEPART(YEAR, @InputDate) >= 2007 THEN
DATEADD(
SECOND,
-1,
DATEADD(
HOUR,
8,
DATEADD(
DAY,
((CEILING((CAST(17 AS DECIMAL(8, 2)) % DATEPART(dw, @DST_End))
/ 10
) * 7
) + 1
) - DATEPART(dw, @DST_End),
@DST_End
)
)
)
ELSE
DATEADD(SECOND, -1, DATEADD(HOUR, 8, DATEADD(DAY, 0 - (DATEPART(dw, @DST_End) - 1), @DST_End)))
END,
@GMT_Offset_Destination = -360;
RETURN CASE
WHEN @InputDate
BETWEEN @DST_Start AND @DST_End THEN
DATEADD(MINUTE, @GMT_Offset_Destination + 60, @InputDate)
ELSE
DATEADD(MINUTE, @GMT_Offset_Destination, @InputDate)
END;
END;