Determining daylight-saving time in Central European TimeCalculating a time in a time zone from multiple dates in SQLSaving and updating recordsIs it Friday yet?Cluster date time valuesSelecting time metadata off a calendar tableStart and end times of recurring eventsCorrecting time in DST gap using Joda TimeImplementing a week schedule class in C#Count occurrences of date-time in large CSVAlgorithm to find the number of years, months, days, etc between two dates

How to make a list of partial sums using forEach

If A is dense in Q, then it must be dense in R.

Deciphering cause of death?

Personal or impersonal in a technical resume

ContourPlot — How do I color by contour curvature?

How do I tell my boss that I'm quitting in 15 days (a colleague left this week)

In One Punch Man, is King actually weak?

Would this string work as string?

Echo with obfuscation

What does "tick" mean in this sentence?

What the heck is gets(stdin) on site coderbyte?

How much do grades matter for a future academia position?

When and why was runway 07/25 at Kai Tak removed?

Why the "ls" command is showing the permissions of files in a FAT32 partition?

Check if object is null and return null

What is this high flying aircraft over Pennsylvania?

Has the laser at Magurele, Romania reached a tenth of the Sun's power?

Should I assume I have passed probation?

Why do Radio Buttons not fill the entire outer circle?

Identifying "long and narrow" polygons in with PostGIS

Why does a 97 / 92 key piano exist by Bösendorfer?

Why is the sun approximated as a black body at ~ 5800 K?

Can I cause damage to electrical appliances by unplugging them when they are turned on?

Overlapping circles covering polygon



Determining daylight-saving time in Central European Time


Calculating a time in a time zone from multiple dates in SQLSaving and updating recordsIs it Friday yet?Cluster date time valuesSelecting time metadata off a calendar tableStart and end times of recurring eventsCorrecting time in DST gap using Joda TimeImplementing a week schedule class in C#Count occurrences of date-time in large CSVAlgorithm to find the number of years, months, days, etc between two dates













0












$begingroup$


The following constellation:



Our applications passes date&time around (in the most horrible way possible).



We want to simplify this. Instead of a culture-specific string like '31.12.2019', we're now passing an ecma-timestamp (the number of milliseconds between the point in time in UTC and 1970-01-01 00:00:00 UTC that is).



Now an additional complication:



Our pitiful application historically has saved all datetime values in the database as local time WITH DAYLIGHT-SAVING (central European summer or winter time, depending on the date) instead of UTC.



Now, central European summer time (CEST) is UTC+2, while central European winter time (CET) is UTC+1.



For the adjustment between summer and winter time, the following rules are applied:




  • The change from winter time to summer time is on the last Sunday of March



    • On the last Sunday morning of March, the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)



  • The change from summer time to winter time is on the last Sunday of October:



    • On the last Sunday morning of October, the clocks will be put backward from 03:00 to 02:00 (one wins an hour)


As you might realize from looking at the definition, the change from summer to winter time presents a discontinuity range, in which a given local-time value can be both summer or winter time... (but not the change from winter to summer time)



Now, I have written the below functions to convert local/UTC-time into an ECMA-timestamp, and you can specify if the input datetime is UTC or localtime.



I haven't had the time to test it all too extensively, but I'd like to collect a second opinion on how to handle the times between 02 and 03 o'clock at the last Sunday of October...



  • Would you handle the conversion the same? (apart from the fact that ideally, the conversion would be avoided / data changed to UTC)

  • Do you spot any errors?

  • Thoughts on what best to do between 02 and 03



PRINT 'Begin Executing "01_fn_dtLastSundayInMonth.sql"' 

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtLastSundayInMonth]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtLastSundayInMonth]() RETURNS int BEGIN RETURN 0 END ')
END
GO



/*
-- This is for testing
SET DATEFIRST 3; -- Monday

WITH CTE AS (

SELECT 1 AS i, CAST('20190101' AS datetime) AS mydate
UNION ALL

SELECT i+1 AS i, DATEADD(month, 1, CTE.mydate) AS mydate
FROM CTE WHERE i < 100
)

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('17530101') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('17530101') AS Control

UNION ALL

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('99991231') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('99991231') AS Control

UNION ALL

SELECT
mydate
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,DATEADD(day,DATEDIFF(day,'19000107', DATEADD(MONTH, DATEDIFF(MONTH, 0, mydate, 30))/7*7,'19000107') AS Control
FROM CTE

*/


-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Return Datum von letztem Sonntag im Monat
-- mit gleichem Jahr und Monat wie @in_DateTime
-- =====================================================================
ALTER FUNCTION [dbo].[fn_dtLastSundayInMonth](@in_DateTime datetime )
RETURNS DateTime
AS
BEGIN
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
DECLARE @dtReturnValue AS DateTime
-- 26.12.9999 SO
IF @in_DateTime >= CAST('99991201' AS datetime)
RETURN CAST('99991226' AS datetime);

-- @dtReturnValue is now last day of month
SET @dtReturnValue = DATEADD
(
DAY
,-1
,DATEADD
(
MONTH
,1
,CAST(CAST(YEAR(@in_DateTime) AS varchar(4)) + RIGHT('00' + CAST(MONTH(@in_DateTime) AS varchar(2)), 2) + '01' AS datetime)
)
)
;

-- SET DATEFIRST 1 -- Monday - Super easy !
-- SET DATEFIRST != 1 - PHUK THIS !
SET @dtReturnValue = DATEADD
(
day
,
-
(

(
-- DATEPART(WEEKDAY, @lastDayofMonth) -- with SET DATEFIRST 1
DATEPART(WEEKDAY, @dtReturnValue) + @@DATEFIRST - 2 % 7 + 1
)
%7
)
, @dtReturnValue
);

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "01_fn_dtLastSundayInMonth.sql"'


GO





PRINT 'Begin Executing "02_fn_dtIsCEST.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtIsCEST]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtIsCEST]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtIsCEST('2019-03-31T01:00:00'), dbo.fn_dtIsCEST('2019-03-31T04:00:00')
ALTER FUNCTION [dbo].[fn_dtIsCEST](@in_DateTime datetime )
RETURNS bit
AS
BEGIN
DECLARE @dtReturnValue AS bit

-- https://www.linker.ch/eigenlink/sommerzeit_winterzeit.htm

-- the change from winter time to summer time is on the last sunday of March
-- the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)

-- the change from summer time to winter time is on the last sunday of October:
-- the clocks will be put backward from 03:00 to 02:00 (one wins an hour).

DECLARE @beginSummerTime datetime
SET @beginSummerTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 2, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginSummerTime = DATEADD(HOUR, 2, @beginSummerTime)

DECLARE @beginWinterTime datetime
SET @beginWinterTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 9, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginWinterTime = DATEADD(HOUR, 2, @beginWinterTime)

SET @dtReturnValue = 0;
IF @in_DateTime >= @beginSummerTime AND @in_DateTime < @beginWinterTime
BEGIN
SET @dtReturnValue = 1;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "02_fn_dtIsCEST.sql"'


GO





PRINT 'Begin Executing "03_fn_dtToEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtToEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtToEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtToEcmaTimeStamp('2019-03-31T01:00:00', 1), dbo.fn_dtToEcmaTimeStamp('2019-03-31T04:00:00', 1)
ALTER FUNCTION [dbo].[fn_dtToEcmaTimeStamp](@in_DateTime datetime, @in_convert_to_utc bit)
RETURNS bigint
AS
BEGIN
DECLARE @dtReturnValue AS bigint

IF @in_convert_to_utc = 1
BEGIN
SET @in_DateTime =
CASE WHEN dbo.fn_dtIsCEST(@in_DateTime) = 1
THEN DATEADD(HOUR, -2, @in_DateTime)
ELSE DATEADD(HOUR, -1, @in_DateTime)
END;
END

SET @dtReturnValue =
CAST
(
DATEDIFF
(
HOUR
,CAST('19700101' AS datetime)
,@in_DateTime
)
AS bigint
) *60*60*1000
+
DATEDIFF
(
MILLISECOND
,CAST(FLOOR(CAST(@in_DateTime AS float)) AS datetime)
,@in_DateTime
) % (60*60*1000)
;

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "03_fn_dtToEcmaTimeStamp.sql"'


GO





PRINT 'Begin Executing "04_fn_dtFromEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtFromEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtFromEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO



-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtFromEcmaTimeStamp('1551437088122', 1), dbo.fn_dtFromEcmaTimeStamp('1554069600000', 1)
ALTER FUNCTION [dbo].[fn_dtFromEcmaTimeStamp](@in_timestamp bigint, @in_convert_to_localtime bit)
RETURNS datetime
AS
BEGIN
DECLARE @dtReturnValue AS datetime
DECLARE @hours int
SET @hours = @in_timestamp /(1000*60*60);

DECLARE @milliseconds int
SET @milliseconds = @in_timestamp - (@in_timestamp /(1000*60*60))*(1000*60*60);


SET @dtReturnValue = DATEADD
(
MILLISECOND, @milliseconds,
DATEADD(hour, @hours, CAST('19700101' AS datetime))
)


IF @in_convert_to_localtime = 1
BEGIN
SET @dtReturnValue = DATEADD(HOUR, 1, @dtReturnValue)
SET @dtReturnValue =
CASE WHEN dbo.fn_dtIsCEST(@dtReturnValue) = 1
THEN DATEADD(HOUR, 1, @dtReturnValue)
ELSE @dtReturnValue
END;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "04_fn_dtFromEcmaTimeStamp.sql"'


GO









share|improve this question









New contributor




Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$











  • $begingroup$
    "and you can specify if the input datetime is UTC or localtime" Why not store all dates/times in the exact same timezone and let the client handle the conversion to whatever time the viewer wants?
    $endgroup$
    – Mast
    13 hours ago










  • $begingroup$
    Is this all supposed to be one query or multiple queries that accidentally got stacked together in one codeblock?
    $endgroup$
    – Mast
    12 hours ago










  • $begingroup$
    @Mast: Because several very large application(s) that handles time that wrong internally just works with local time. You can't just change the data on the database, you first need to change the application as well. By specifying it as parameter, you can use UTC where changed, and localtime where the change still needs to be done.
    $endgroup$
    – Quandary
    12 hours ago






  • 1




    $begingroup$
    @Mast: These are 4 functions that were merged into one script. Function 1 to get the last sunday of month x in year y, function 2 to determine if a local datetime is summer or winter-time, function 3 to to convert datetime to ecma-timestamp, function 4 to convert from ecma-timestamp to datetime.
    $endgroup$
    – Quandary
    12 hours ago







  • 1




    $begingroup$
    I don't envy you for your problem. A thought I had that may or may not apply: If you have an autoincrement primary key or another way to determine ordering between records aside from the date, you can use that to find out when the DST rollover happened for one given period. That's unfortunately rather nontrivial and depends on a column existing that is monotonous as a function of time...
    $endgroup$
    – Vogel612
    12 hours ago















0












$begingroup$


The following constellation:



Our applications passes date&time around (in the most horrible way possible).



We want to simplify this. Instead of a culture-specific string like '31.12.2019', we're now passing an ecma-timestamp (the number of milliseconds between the point in time in UTC and 1970-01-01 00:00:00 UTC that is).



Now an additional complication:



Our pitiful application historically has saved all datetime values in the database as local time WITH DAYLIGHT-SAVING (central European summer or winter time, depending on the date) instead of UTC.



Now, central European summer time (CEST) is UTC+2, while central European winter time (CET) is UTC+1.



For the adjustment between summer and winter time, the following rules are applied:




  • The change from winter time to summer time is on the last Sunday of March



    • On the last Sunday morning of March, the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)



  • The change from summer time to winter time is on the last Sunday of October:



    • On the last Sunday morning of October, the clocks will be put backward from 03:00 to 02:00 (one wins an hour)


As you might realize from looking at the definition, the change from summer to winter time presents a discontinuity range, in which a given local-time value can be both summer or winter time... (but not the change from winter to summer time)



Now, I have written the below functions to convert local/UTC-time into an ECMA-timestamp, and you can specify if the input datetime is UTC or localtime.



I haven't had the time to test it all too extensively, but I'd like to collect a second opinion on how to handle the times between 02 and 03 o'clock at the last Sunday of October...



  • Would you handle the conversion the same? (apart from the fact that ideally, the conversion would be avoided / data changed to UTC)

  • Do you spot any errors?

  • Thoughts on what best to do between 02 and 03



PRINT 'Begin Executing "01_fn_dtLastSundayInMonth.sql"' 

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtLastSundayInMonth]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtLastSundayInMonth]() RETURNS int BEGIN RETURN 0 END ')
END
GO



/*
-- This is for testing
SET DATEFIRST 3; -- Monday

WITH CTE AS (

SELECT 1 AS i, CAST('20190101' AS datetime) AS mydate
UNION ALL

SELECT i+1 AS i, DATEADD(month, 1, CTE.mydate) AS mydate
FROM CTE WHERE i < 100
)

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('17530101') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('17530101') AS Control

UNION ALL

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('99991231') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('99991231') AS Control

UNION ALL

SELECT
mydate
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,DATEADD(day,DATEDIFF(day,'19000107', DATEADD(MONTH, DATEDIFF(MONTH, 0, mydate, 30))/7*7,'19000107') AS Control
FROM CTE

*/


-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Return Datum von letztem Sonntag im Monat
-- mit gleichem Jahr und Monat wie @in_DateTime
-- =====================================================================
ALTER FUNCTION [dbo].[fn_dtLastSundayInMonth](@in_DateTime datetime )
RETURNS DateTime
AS
BEGIN
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
DECLARE @dtReturnValue AS DateTime
-- 26.12.9999 SO
IF @in_DateTime >= CAST('99991201' AS datetime)
RETURN CAST('99991226' AS datetime);

-- @dtReturnValue is now last day of month
SET @dtReturnValue = DATEADD
(
DAY
,-1
,DATEADD
(
MONTH
,1
,CAST(CAST(YEAR(@in_DateTime) AS varchar(4)) + RIGHT('00' + CAST(MONTH(@in_DateTime) AS varchar(2)), 2) + '01' AS datetime)
)
)
;

-- SET DATEFIRST 1 -- Monday - Super easy !
-- SET DATEFIRST != 1 - PHUK THIS !
SET @dtReturnValue = DATEADD
(
day
,
-
(

(
-- DATEPART(WEEKDAY, @lastDayofMonth) -- with SET DATEFIRST 1
DATEPART(WEEKDAY, @dtReturnValue) + @@DATEFIRST - 2 % 7 + 1
)
%7
)
, @dtReturnValue
);

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "01_fn_dtLastSundayInMonth.sql"'


GO





PRINT 'Begin Executing "02_fn_dtIsCEST.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtIsCEST]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtIsCEST]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtIsCEST('2019-03-31T01:00:00'), dbo.fn_dtIsCEST('2019-03-31T04:00:00')
ALTER FUNCTION [dbo].[fn_dtIsCEST](@in_DateTime datetime )
RETURNS bit
AS
BEGIN
DECLARE @dtReturnValue AS bit

-- https://www.linker.ch/eigenlink/sommerzeit_winterzeit.htm

-- the change from winter time to summer time is on the last sunday of March
-- the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)

-- the change from summer time to winter time is on the last sunday of October:
-- the clocks will be put backward from 03:00 to 02:00 (one wins an hour).

DECLARE @beginSummerTime datetime
SET @beginSummerTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 2, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginSummerTime = DATEADD(HOUR, 2, @beginSummerTime)

DECLARE @beginWinterTime datetime
SET @beginWinterTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 9, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginWinterTime = DATEADD(HOUR, 2, @beginWinterTime)

SET @dtReturnValue = 0;
IF @in_DateTime >= @beginSummerTime AND @in_DateTime < @beginWinterTime
BEGIN
SET @dtReturnValue = 1;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "02_fn_dtIsCEST.sql"'


GO





PRINT 'Begin Executing "03_fn_dtToEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtToEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtToEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtToEcmaTimeStamp('2019-03-31T01:00:00', 1), dbo.fn_dtToEcmaTimeStamp('2019-03-31T04:00:00', 1)
ALTER FUNCTION [dbo].[fn_dtToEcmaTimeStamp](@in_DateTime datetime, @in_convert_to_utc bit)
RETURNS bigint
AS
BEGIN
DECLARE @dtReturnValue AS bigint

IF @in_convert_to_utc = 1
BEGIN
SET @in_DateTime =
CASE WHEN dbo.fn_dtIsCEST(@in_DateTime) = 1
THEN DATEADD(HOUR, -2, @in_DateTime)
ELSE DATEADD(HOUR, -1, @in_DateTime)
END;
END

SET @dtReturnValue =
CAST
(
DATEDIFF
(
HOUR
,CAST('19700101' AS datetime)
,@in_DateTime
)
AS bigint
) *60*60*1000
+
DATEDIFF
(
MILLISECOND
,CAST(FLOOR(CAST(@in_DateTime AS float)) AS datetime)
,@in_DateTime
) % (60*60*1000)
;

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "03_fn_dtToEcmaTimeStamp.sql"'


GO





PRINT 'Begin Executing "04_fn_dtFromEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtFromEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtFromEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO



-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtFromEcmaTimeStamp('1551437088122', 1), dbo.fn_dtFromEcmaTimeStamp('1554069600000', 1)
ALTER FUNCTION [dbo].[fn_dtFromEcmaTimeStamp](@in_timestamp bigint, @in_convert_to_localtime bit)
RETURNS datetime
AS
BEGIN
DECLARE @dtReturnValue AS datetime
DECLARE @hours int
SET @hours = @in_timestamp /(1000*60*60);

DECLARE @milliseconds int
SET @milliseconds = @in_timestamp - (@in_timestamp /(1000*60*60))*(1000*60*60);


SET @dtReturnValue = DATEADD
(
MILLISECOND, @milliseconds,
DATEADD(hour, @hours, CAST('19700101' AS datetime))
)


IF @in_convert_to_localtime = 1
BEGIN
SET @dtReturnValue = DATEADD(HOUR, 1, @dtReturnValue)
SET @dtReturnValue =
CASE WHEN dbo.fn_dtIsCEST(@dtReturnValue) = 1
THEN DATEADD(HOUR, 1, @dtReturnValue)
ELSE @dtReturnValue
END;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "04_fn_dtFromEcmaTimeStamp.sql"'


GO









share|improve this question









New contributor




Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$











  • $begingroup$
    "and you can specify if the input datetime is UTC or localtime" Why not store all dates/times in the exact same timezone and let the client handle the conversion to whatever time the viewer wants?
    $endgroup$
    – Mast
    13 hours ago










  • $begingroup$
    Is this all supposed to be one query or multiple queries that accidentally got stacked together in one codeblock?
    $endgroup$
    – Mast
    12 hours ago










  • $begingroup$
    @Mast: Because several very large application(s) that handles time that wrong internally just works with local time. You can't just change the data on the database, you first need to change the application as well. By specifying it as parameter, you can use UTC where changed, and localtime where the change still needs to be done.
    $endgroup$
    – Quandary
    12 hours ago






  • 1




    $begingroup$
    @Mast: These are 4 functions that were merged into one script. Function 1 to get the last sunday of month x in year y, function 2 to determine if a local datetime is summer or winter-time, function 3 to to convert datetime to ecma-timestamp, function 4 to convert from ecma-timestamp to datetime.
    $endgroup$
    – Quandary
    12 hours ago







  • 1




    $begingroup$
    I don't envy you for your problem. A thought I had that may or may not apply: If you have an autoincrement primary key or another way to determine ordering between records aside from the date, you can use that to find out when the DST rollover happened for one given period. That's unfortunately rather nontrivial and depends on a column existing that is monotonous as a function of time...
    $endgroup$
    – Vogel612
    12 hours ago













0












0








0





$begingroup$


The following constellation:



Our applications passes date&time around (in the most horrible way possible).



We want to simplify this. Instead of a culture-specific string like '31.12.2019', we're now passing an ecma-timestamp (the number of milliseconds between the point in time in UTC and 1970-01-01 00:00:00 UTC that is).



Now an additional complication:



Our pitiful application historically has saved all datetime values in the database as local time WITH DAYLIGHT-SAVING (central European summer or winter time, depending on the date) instead of UTC.



Now, central European summer time (CEST) is UTC+2, while central European winter time (CET) is UTC+1.



For the adjustment between summer and winter time, the following rules are applied:




  • The change from winter time to summer time is on the last Sunday of March



    • On the last Sunday morning of March, the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)



  • The change from summer time to winter time is on the last Sunday of October:



    • On the last Sunday morning of October, the clocks will be put backward from 03:00 to 02:00 (one wins an hour)


As you might realize from looking at the definition, the change from summer to winter time presents a discontinuity range, in which a given local-time value can be both summer or winter time... (but not the change from winter to summer time)



Now, I have written the below functions to convert local/UTC-time into an ECMA-timestamp, and you can specify if the input datetime is UTC or localtime.



I haven't had the time to test it all too extensively, but I'd like to collect a second opinion on how to handle the times between 02 and 03 o'clock at the last Sunday of October...



  • Would you handle the conversion the same? (apart from the fact that ideally, the conversion would be avoided / data changed to UTC)

  • Do you spot any errors?

  • Thoughts on what best to do between 02 and 03



PRINT 'Begin Executing "01_fn_dtLastSundayInMonth.sql"' 

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtLastSundayInMonth]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtLastSundayInMonth]() RETURNS int BEGIN RETURN 0 END ')
END
GO



/*
-- This is for testing
SET DATEFIRST 3; -- Monday

WITH CTE AS (

SELECT 1 AS i, CAST('20190101' AS datetime) AS mydate
UNION ALL

SELECT i+1 AS i, DATEADD(month, 1, CTE.mydate) AS mydate
FROM CTE WHERE i < 100
)

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('17530101') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('17530101') AS Control

UNION ALL

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('99991231') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('99991231') AS Control

UNION ALL

SELECT
mydate
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,DATEADD(day,DATEDIFF(day,'19000107', DATEADD(MONTH, DATEDIFF(MONTH, 0, mydate, 30))/7*7,'19000107') AS Control
FROM CTE

*/


-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Return Datum von letztem Sonntag im Monat
-- mit gleichem Jahr und Monat wie @in_DateTime
-- =====================================================================
ALTER FUNCTION [dbo].[fn_dtLastSundayInMonth](@in_DateTime datetime )
RETURNS DateTime
AS
BEGIN
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
DECLARE @dtReturnValue AS DateTime
-- 26.12.9999 SO
IF @in_DateTime >= CAST('99991201' AS datetime)
RETURN CAST('99991226' AS datetime);

-- @dtReturnValue is now last day of month
SET @dtReturnValue = DATEADD
(
DAY
,-1
,DATEADD
(
MONTH
,1
,CAST(CAST(YEAR(@in_DateTime) AS varchar(4)) + RIGHT('00' + CAST(MONTH(@in_DateTime) AS varchar(2)), 2) + '01' AS datetime)
)
)
;

-- SET DATEFIRST 1 -- Monday - Super easy !
-- SET DATEFIRST != 1 - PHUK THIS !
SET @dtReturnValue = DATEADD
(
day
,
-
(

(
-- DATEPART(WEEKDAY, @lastDayofMonth) -- with SET DATEFIRST 1
DATEPART(WEEKDAY, @dtReturnValue) + @@DATEFIRST - 2 % 7 + 1
)
%7
)
, @dtReturnValue
);

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "01_fn_dtLastSundayInMonth.sql"'


GO





PRINT 'Begin Executing "02_fn_dtIsCEST.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtIsCEST]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtIsCEST]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtIsCEST('2019-03-31T01:00:00'), dbo.fn_dtIsCEST('2019-03-31T04:00:00')
ALTER FUNCTION [dbo].[fn_dtIsCEST](@in_DateTime datetime )
RETURNS bit
AS
BEGIN
DECLARE @dtReturnValue AS bit

-- https://www.linker.ch/eigenlink/sommerzeit_winterzeit.htm

-- the change from winter time to summer time is on the last sunday of March
-- the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)

-- the change from summer time to winter time is on the last sunday of October:
-- the clocks will be put backward from 03:00 to 02:00 (one wins an hour).

DECLARE @beginSummerTime datetime
SET @beginSummerTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 2, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginSummerTime = DATEADD(HOUR, 2, @beginSummerTime)

DECLARE @beginWinterTime datetime
SET @beginWinterTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 9, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginWinterTime = DATEADD(HOUR, 2, @beginWinterTime)

SET @dtReturnValue = 0;
IF @in_DateTime >= @beginSummerTime AND @in_DateTime < @beginWinterTime
BEGIN
SET @dtReturnValue = 1;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "02_fn_dtIsCEST.sql"'


GO





PRINT 'Begin Executing "03_fn_dtToEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtToEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtToEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtToEcmaTimeStamp('2019-03-31T01:00:00', 1), dbo.fn_dtToEcmaTimeStamp('2019-03-31T04:00:00', 1)
ALTER FUNCTION [dbo].[fn_dtToEcmaTimeStamp](@in_DateTime datetime, @in_convert_to_utc bit)
RETURNS bigint
AS
BEGIN
DECLARE @dtReturnValue AS bigint

IF @in_convert_to_utc = 1
BEGIN
SET @in_DateTime =
CASE WHEN dbo.fn_dtIsCEST(@in_DateTime) = 1
THEN DATEADD(HOUR, -2, @in_DateTime)
ELSE DATEADD(HOUR, -1, @in_DateTime)
END;
END

SET @dtReturnValue =
CAST
(
DATEDIFF
(
HOUR
,CAST('19700101' AS datetime)
,@in_DateTime
)
AS bigint
) *60*60*1000
+
DATEDIFF
(
MILLISECOND
,CAST(FLOOR(CAST(@in_DateTime AS float)) AS datetime)
,@in_DateTime
) % (60*60*1000)
;

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "03_fn_dtToEcmaTimeStamp.sql"'


GO





PRINT 'Begin Executing "04_fn_dtFromEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtFromEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtFromEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO



-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtFromEcmaTimeStamp('1551437088122', 1), dbo.fn_dtFromEcmaTimeStamp('1554069600000', 1)
ALTER FUNCTION [dbo].[fn_dtFromEcmaTimeStamp](@in_timestamp bigint, @in_convert_to_localtime bit)
RETURNS datetime
AS
BEGIN
DECLARE @dtReturnValue AS datetime
DECLARE @hours int
SET @hours = @in_timestamp /(1000*60*60);

DECLARE @milliseconds int
SET @milliseconds = @in_timestamp - (@in_timestamp /(1000*60*60))*(1000*60*60);


SET @dtReturnValue = DATEADD
(
MILLISECOND, @milliseconds,
DATEADD(hour, @hours, CAST('19700101' AS datetime))
)


IF @in_convert_to_localtime = 1
BEGIN
SET @dtReturnValue = DATEADD(HOUR, 1, @dtReturnValue)
SET @dtReturnValue =
CASE WHEN dbo.fn_dtIsCEST(@dtReturnValue) = 1
THEN DATEADD(HOUR, 1, @dtReturnValue)
ELSE @dtReturnValue
END;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "04_fn_dtFromEcmaTimeStamp.sql"'


GO









share|improve this question









New contributor




Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




The following constellation:



Our applications passes date&time around (in the most horrible way possible).



We want to simplify this. Instead of a culture-specific string like '31.12.2019', we're now passing an ecma-timestamp (the number of milliseconds between the point in time in UTC and 1970-01-01 00:00:00 UTC that is).



Now an additional complication:



Our pitiful application historically has saved all datetime values in the database as local time WITH DAYLIGHT-SAVING (central European summer or winter time, depending on the date) instead of UTC.



Now, central European summer time (CEST) is UTC+2, while central European winter time (CET) is UTC+1.



For the adjustment between summer and winter time, the following rules are applied:




  • The change from winter time to summer time is on the last Sunday of March



    • On the last Sunday morning of March, the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)



  • The change from summer time to winter time is on the last Sunday of October:



    • On the last Sunday morning of October, the clocks will be put backward from 03:00 to 02:00 (one wins an hour)


As you might realize from looking at the definition, the change from summer to winter time presents a discontinuity range, in which a given local-time value can be both summer or winter time... (but not the change from winter to summer time)



Now, I have written the below functions to convert local/UTC-time into an ECMA-timestamp, and you can specify if the input datetime is UTC or localtime.



I haven't had the time to test it all too extensively, but I'd like to collect a second opinion on how to handle the times between 02 and 03 o'clock at the last Sunday of October...



  • Would you handle the conversion the same? (apart from the fact that ideally, the conversion would be avoided / data changed to UTC)

  • Do you spot any errors?

  • Thoughts on what best to do between 02 and 03



PRINT 'Begin Executing "01_fn_dtLastSundayInMonth.sql"' 

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtLastSundayInMonth]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtLastSundayInMonth]() RETURNS int BEGIN RETURN 0 END ')
END
GO



/*
-- This is for testing
SET DATEFIRST 3; -- Monday

WITH CTE AS (

SELECT 1 AS i, CAST('20190101' AS datetime) AS mydate
UNION ALL

SELECT i+1 AS i, DATEADD(month, 1, CTE.mydate) AS mydate
FROM CTE WHERE i < 100
)

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('17530101') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('17530101') AS Control

UNION ALL

SELECT -666 AS i, dbo.fn_dtLastSundayInMonth('99991231') AS lastSundayInMonth, dbo.fn_dtLastSundayInMonth('99991231') AS Control

UNION ALL

SELECT
mydate
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,dbo.fn_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,DATEADD(day,DATEDIFF(day,'19000107', DATEADD(MONTH, DATEDIFF(MONTH, 0, mydate, 30))/7*7,'19000107') AS Control
FROM CTE

*/


-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Return Datum von letztem Sonntag im Monat
-- mit gleichem Jahr und Monat wie @in_DateTime
-- =====================================================================
ALTER FUNCTION [dbo].[fn_dtLastSundayInMonth](@in_DateTime datetime )
RETURNS DateTime
AS
BEGIN
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
DECLARE @dtReturnValue AS DateTime
-- 26.12.9999 SO
IF @in_DateTime >= CAST('99991201' AS datetime)
RETURN CAST('99991226' AS datetime);

-- @dtReturnValue is now last day of month
SET @dtReturnValue = DATEADD
(
DAY
,-1
,DATEADD
(
MONTH
,1
,CAST(CAST(YEAR(@in_DateTime) AS varchar(4)) + RIGHT('00' + CAST(MONTH(@in_DateTime) AS varchar(2)), 2) + '01' AS datetime)
)
)
;

-- SET DATEFIRST 1 -- Monday - Super easy !
-- SET DATEFIRST != 1 - PHUK THIS !
SET @dtReturnValue = DATEADD
(
day
,
-
(

(
-- DATEPART(WEEKDAY, @lastDayofMonth) -- with SET DATEFIRST 1
DATEPART(WEEKDAY, @dtReturnValue) + @@DATEFIRST - 2 % 7 + 1
)
%7
)
, @dtReturnValue
);

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "01_fn_dtLastSundayInMonth.sql"'


GO





PRINT 'Begin Executing "02_fn_dtIsCEST.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtIsCEST]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtIsCEST]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtIsCEST('2019-03-31T01:00:00'), dbo.fn_dtIsCEST('2019-03-31T04:00:00')
ALTER FUNCTION [dbo].[fn_dtIsCEST](@in_DateTime datetime )
RETURNS bit
AS
BEGIN
DECLARE @dtReturnValue AS bit

-- https://www.linker.ch/eigenlink/sommerzeit_winterzeit.htm

-- the change from winter time to summer time is on the last sunday of March
-- the clocks will be put forward from 02:00 to 03:00. (one 'loses' an hour)

-- the change from summer time to winter time is on the last sunday of October:
-- the clocks will be put backward from 03:00 to 02:00 (one wins an hour).

DECLARE @beginSummerTime datetime
SET @beginSummerTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 2, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginSummerTime = DATEADD(HOUR, 2, @beginSummerTime)

DECLARE @beginWinterTime datetime
SET @beginWinterTime = dbo.fn_dtLastSundayInMonth(DATEADD(MONTH, 9, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginWinterTime = DATEADD(HOUR, 2, @beginWinterTime)

SET @dtReturnValue = 0;
IF @in_DateTime >= @beginSummerTime AND @in_DateTime < @beginWinterTime
BEGIN
SET @dtReturnValue = 1;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "02_fn_dtIsCEST.sql"'


GO





PRINT 'Begin Executing "03_fn_dtToEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtToEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtToEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO




-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtToEcmaTimeStamp('2019-03-31T01:00:00', 1), dbo.fn_dtToEcmaTimeStamp('2019-03-31T04:00:00', 1)
ALTER FUNCTION [dbo].[fn_dtToEcmaTimeStamp](@in_DateTime datetime, @in_convert_to_utc bit)
RETURNS bigint
AS
BEGIN
DECLARE @dtReturnValue AS bigint

IF @in_convert_to_utc = 1
BEGIN
SET @in_DateTime =
CASE WHEN dbo.fn_dtIsCEST(@in_DateTime) = 1
THEN DATEADD(HOUR, -2, @in_DateTime)
ELSE DATEADD(HOUR, -1, @in_DateTime)
END;
END

SET @dtReturnValue =
CAST
(
DATEDIFF
(
HOUR
,CAST('19700101' AS datetime)
,@in_DateTime
)
AS bigint
) *60*60*1000
+
DATEDIFF
(
MILLISECOND
,CAST(FLOOR(CAST(@in_DateTime AS float)) AS datetime)
,@in_DateTime
) % (60*60*1000)
;

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "03_fn_dtToEcmaTimeStamp.sql"'


GO





PRINT 'Begin Executing "04_fn_dtFromEcmaTimeStamp.sql"'

GO



IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_dtFromEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fn_dtFromEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO



-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fn_dtFromEcmaTimeStamp('1551437088122', 1), dbo.fn_dtFromEcmaTimeStamp('1554069600000', 1)
ALTER FUNCTION [dbo].[fn_dtFromEcmaTimeStamp](@in_timestamp bigint, @in_convert_to_localtime bit)
RETURNS datetime
AS
BEGIN
DECLARE @dtReturnValue AS datetime
DECLARE @hours int
SET @hours = @in_timestamp /(1000*60*60);

DECLARE @milliseconds int
SET @milliseconds = @in_timestamp - (@in_timestamp /(1000*60*60))*(1000*60*60);


SET @dtReturnValue = DATEADD
(
MILLISECOND, @milliseconds,
DATEADD(hour, @hours, CAST('19700101' AS datetime))
)


IF @in_convert_to_localtime = 1
BEGIN
SET @dtReturnValue = DATEADD(HOUR, 1, @dtReturnValue)
SET @dtReturnValue =
CASE WHEN dbo.fn_dtIsCEST(@dtReturnValue) = 1
THEN DATEADD(HOUR, 1, @dtReturnValue)
ELSE @dtReturnValue
END;
END

RETURN @dtReturnValue;
END


GO



GO


PRINT 'Done Executing "04_fn_dtFromEcmaTimeStamp.sql"'


GO






sql datetime t-sql






share|improve this question









New contributor




Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 1 min ago









Jamal

30.4k11121227




30.4k11121227






New contributor




Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 14 hours ago









QuandaryQuandary

1013




1013




New contributor




Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Quandary is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • $begingroup$
    "and you can specify if the input datetime is UTC or localtime" Why not store all dates/times in the exact same timezone and let the client handle the conversion to whatever time the viewer wants?
    $endgroup$
    – Mast
    13 hours ago










  • $begingroup$
    Is this all supposed to be one query or multiple queries that accidentally got stacked together in one codeblock?
    $endgroup$
    – Mast
    12 hours ago










  • $begingroup$
    @Mast: Because several very large application(s) that handles time that wrong internally just works with local time. You can't just change the data on the database, you first need to change the application as well. By specifying it as parameter, you can use UTC where changed, and localtime where the change still needs to be done.
    $endgroup$
    – Quandary
    12 hours ago






  • 1




    $begingroup$
    @Mast: These are 4 functions that were merged into one script. Function 1 to get the last sunday of month x in year y, function 2 to determine if a local datetime is summer or winter-time, function 3 to to convert datetime to ecma-timestamp, function 4 to convert from ecma-timestamp to datetime.
    $endgroup$
    – Quandary
    12 hours ago







  • 1




    $begingroup$
    I don't envy you for your problem. A thought I had that may or may not apply: If you have an autoincrement primary key or another way to determine ordering between records aside from the date, you can use that to find out when the DST rollover happened for one given period. That's unfortunately rather nontrivial and depends on a column existing that is monotonous as a function of time...
    $endgroup$
    – Vogel612
    12 hours ago
















  • $begingroup$
    "and you can specify if the input datetime is UTC or localtime" Why not store all dates/times in the exact same timezone and let the client handle the conversion to whatever time the viewer wants?
    $endgroup$
    – Mast
    13 hours ago










  • $begingroup$
    Is this all supposed to be one query or multiple queries that accidentally got stacked together in one codeblock?
    $endgroup$
    – Mast
    12 hours ago










  • $begingroup$
    @Mast: Because several very large application(s) that handles time that wrong internally just works with local time. You can't just change the data on the database, you first need to change the application as well. By specifying it as parameter, you can use UTC where changed, and localtime where the change still needs to be done.
    $endgroup$
    – Quandary
    12 hours ago






  • 1




    $begingroup$
    @Mast: These are 4 functions that were merged into one script. Function 1 to get the last sunday of month x in year y, function 2 to determine if a local datetime is summer or winter-time, function 3 to to convert datetime to ecma-timestamp, function 4 to convert from ecma-timestamp to datetime.
    $endgroup$
    – Quandary
    12 hours ago







  • 1




    $begingroup$
    I don't envy you for your problem. A thought I had that may or may not apply: If you have an autoincrement primary key or another way to determine ordering between records aside from the date, you can use that to find out when the DST rollover happened for one given period. That's unfortunately rather nontrivial and depends on a column existing that is monotonous as a function of time...
    $endgroup$
    – Vogel612
    12 hours ago















$begingroup$
"and you can specify if the input datetime is UTC or localtime" Why not store all dates/times in the exact same timezone and let the client handle the conversion to whatever time the viewer wants?
$endgroup$
– Mast
13 hours ago




$begingroup$
"and you can specify if the input datetime is UTC or localtime" Why not store all dates/times in the exact same timezone and let the client handle the conversion to whatever time the viewer wants?
$endgroup$
– Mast
13 hours ago












$begingroup$
Is this all supposed to be one query or multiple queries that accidentally got stacked together in one codeblock?
$endgroup$
– Mast
12 hours ago




$begingroup$
Is this all supposed to be one query or multiple queries that accidentally got stacked together in one codeblock?
$endgroup$
– Mast
12 hours ago












$begingroup$
@Mast: Because several very large application(s) that handles time that wrong internally just works with local time. You can't just change the data on the database, you first need to change the application as well. By specifying it as parameter, you can use UTC where changed, and localtime where the change still needs to be done.
$endgroup$
– Quandary
12 hours ago




$begingroup$
@Mast: Because several very large application(s) that handles time that wrong internally just works with local time. You can't just change the data on the database, you first need to change the application as well. By specifying it as parameter, you can use UTC where changed, and localtime where the change still needs to be done.
$endgroup$
– Quandary
12 hours ago




1




1




$begingroup$
@Mast: These are 4 functions that were merged into one script. Function 1 to get the last sunday of month x in year y, function 2 to determine if a local datetime is summer or winter-time, function 3 to to convert datetime to ecma-timestamp, function 4 to convert from ecma-timestamp to datetime.
$endgroup$
– Quandary
12 hours ago





$begingroup$
@Mast: These are 4 functions that were merged into one script. Function 1 to get the last sunday of month x in year y, function 2 to determine if a local datetime is summer or winter-time, function 3 to to convert datetime to ecma-timestamp, function 4 to convert from ecma-timestamp to datetime.
$endgroup$
– Quandary
12 hours ago





1




1




$begingroup$
I don't envy you for your problem. A thought I had that may or may not apply: If you have an autoincrement primary key or another way to determine ordering between records aside from the date, you can use that to find out when the DST rollover happened for one given period. That's unfortunately rather nontrivial and depends on a column existing that is monotonous as a function of time...
$endgroup$
– Vogel612
12 hours ago




$begingroup$
I don't envy you for your problem. A thought I had that may or may not apply: If you have an autoincrement primary key or another way to determine ordering between records aside from the date, you can use that to find out when the DST rollover happened for one given period. That's unfortunately rather nontrivial and depends on a column existing that is monotonous as a function of time...
$endgroup$
– Vogel612
12 hours ago










0






active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);






Quandary is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215834%2fdetermining-daylight-saving-time-in-central-european-time%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes








Quandary is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















Quandary is a new contributor. Be nice, and check out our Code of Conduct.












Quandary is a new contributor. Be nice, and check out our Code of Conduct.











Quandary is a new contributor. Be nice, and check out our Code of Conduct.














Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215834%2fdetermining-daylight-saving-time-in-central-european-time%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar