/ Published in: SQL
Many of us have come across cases where we need to convert a time (such as UTC) to local time, but what about those parts of the world where daylight savings time is observed?
This function will return the daylight savings date/time for a given year in accordance with historical records: http://www.energy.ca.gov/daylightsaving.html#chart
This way, no lookup tables are needed. All you have to know is what timezone you are converting from and to, because as long as you have the date when daylight savings begins/ends, then it should be fairly easy to write some case logic to convert the date. This script also contains an example of this function's use by converting UTC to PST.
Caveat: The function can return undesirable results if the SET DATEFIRST statement is set to anything other than Sunday.
This function will return the daylight savings date/time for a given year in accordance with historical records: http://www.energy.ca.gov/daylightsaving.html#chart
This way, no lookup tables are needed. All you have to know is what timezone you are converting from and to, because as long as you have the date when daylight savings begins/ends, then it should be fairly easy to write some case logic to convert the date. This script also contains an example of this function's use by converting UTC to PST.
Caveat: The function can return undesirable results if the SET DATEFIRST statement is set to anything other than Sunday.
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
IF NOT object_id('dbo.udf_GetDaylightSavingsTime') IS NULL DROP FUNCTION dbo.udf_GetDaylightSavingsTime GO CREATE FUNCTION [dbo].udf_GetDaylightSavingsTime(@YEAR INT, @extent VARCHAR(255)) RETURNS datetime /********************************************************************** PROCEDURE: udf_GetDaylightSavingsTime PARAMETERS: @year: the year to return the daylight savings time begin date @extent ('Begin' or 'End'): indicates whether the function returns the begin or end date of daylight savings time APPLICATION: System Support PURPOSE: This procedure will return the date of daylight savings time according to the current federal schedule, which is currently the second Sunday in March: http://www.energy.ca.gov/daylightsaving.html#chart NOTES: This procedure will also return the begin date for the previous schedule which ended in 2006, which was the first Sunday of April EXAMPLES: print dbo.udf_GetDaylightSavingsTime(2003, 'Begin') print dbo.udf_GetDaylightSavingsTime(2003, 'End') print dbo.udf_GetDaylightSavingsTime(2009, 'Begin') print dbo.udf_GetDaylightSavingsTime(2009, 'end') MODIFIED DATE AUTHOR DESCRIPTION -------------- -------------- ------------------------------- **********************************************************************/ AS BEGIN -- function DECLARE @dateTime datetime , @ErrorMessage VARCHAR(1000) , @ProcName VARCHAR(128) SET @ProcName = object_name(@@procid) IF @extent NOT IN('Begin', 'End') BEGIN SET @dateTime = 1/0 END SET @dateTime = CASE @extent WHEN 'Begin' THEN CASE --latest daylight savings time WHEN @YEAR >= 2007 THEN CAST('3/8/' + CAST(@YEAR AS VARCHAR(4)) AS datetime) --old daylight savings time prior to 2007 WHEN @YEAR <= 2006 THEN CAST('4/1/' + CAST(@YEAR AS VARCHAR(4)) AS datetime) END WHEN 'End' THEN CASE --latest daylight savings time WHEN @YEAR >= 2007 THEN CAST('11/1/' + CAST(@YEAR AS VARCHAR(4)) AS datetime) --old daylight savings time prior to 2007 WHEN @YEAR <= 2006 THEN CAST('10/31/' + CAST(@YEAR AS VARCHAR(4)) AS datetime) END END SET @dateTime = CASE WHEN @extent = 'End' AND @YEAR <= 2006 THEN DATEADD(DAY,1-DATEPART(weekday,dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,@dateTime)+1, 0))),dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,@dateTime)+1, 0))) ELSE CASE WHEN datepart(dw, @dateTime) = 1 THEN @dateTime ELSE dateadd(dd, 8 - datepart(dw, @dateTime), @dateTime) END END -- daylight savings time begins at 2 am RETURN CONVERT(VARCHAR(10), @dateTime, 101) + ' 02:00:00' END -- function GO DECLARE @TestyWesty TABLE (UTCDate datetime) --Test DST Begin date INSERT INTO @TestyWesty VALUES('03/08/2009 09:59:59') INSERT INTO @TestyWesty VALUES('03/08/2009 10:00:00') INSERT INTO @TestyWesty VALUES('03/08/2009 10:00:01') --Test DST End date INSERT INTO @TestyWesty VALUES('11/01/2009 08:59:59') INSERT INTO @TestyWesty VALUES('11/01/2009 09:00:00') INSERT INTO @TestyWesty VALUES('11/01/2009 09:00:01') SELECT CASE WHEN dateadd(HOUR, -8, UTCDate) >= dbo.udf_GetDaylightSavingsTime(YEAR(UTCDate), 'Begin') AND dateadd(HOUR, -7, UTCDate) < dbo.udf_GetDaylightSavingsTime(YEAR(UTCDate), 'End') THEN dateadd(HOUR, -7, UTCDate) ELSE dateadd(HOUR, -8, UTCDate) END AS UTCDate FROM @TestyWesty
URL: http://www.sqlservercentral.com/scripts/function/70984/