Determining daylight-saving time in Central European TimeListing the weeks in a given monthLabor percentage and wages from clock in/out and sales recordsIs it Friday yet?PostgreSQL multiple processes and queries or nested queryStart and end times of recurring eventsCorrecting time in DST gap using Joda TimeImplementing a week schedule class in C#Classification of Date/Time/DateTimeCount occurrences of date-time in large CSVAlgorithm to find the number of years, months, days, etc between two dates

Determining multivariate least squares with constraint

Is there a distance limit for minecart tracks?

Identifying "long and narrow" polygons in with PostGIS

El Dorado Word Puzzle II: Videogame Edition

What should be the ideal length of sentences in a blog post for ease of reading?

Is there anyway, I can have two passwords for my wi-fi

How to preserve electronics (computers, iPads and phones) for hundreds of years

Why didn’t Eve recognize the little cockroach as a living organism?

What is the meaning of "You've never met a graph you didn't like?"

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

How do I prevent inappropriate ads from appearing in my game?

Review your own paper in Mathematics

Can you identify this lizard-like creature I observed in the UK?

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

Does Doodling or Improvising on the Piano Have Any Benefits?

How to leave product feedback on macOS?

In One Punch Man, is King actually weak?

Personal or impersonal in a technical resume

Would a primitive species be able to learn English from reading books alone?

The Digit Triangles

Pre-Employment Background Check With Consent For Future Checks

What's the name of the logical fallacy where a debater extends a statement far beyond the original statement to make it true?

Why is participating in the European Parliamentary elections used as a threat?

Possible Eco thriller, man invents a device to remove rain from glass



Determining daylight-saving time in Central European Time


Listing the weeks in a given monthLabor percentage and wages from clock in/out and sales recordsIs it Friday yet?PostgreSQL multiple processes and queries or nested queryStart and end times of recurring eventsCorrecting time in DST gap using Joda TimeImplementing a week schedule class in C#Classification of Date/Time/DateTimeCount 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
    13 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
    13 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
    13 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
    13 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
    13 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
    13 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 11 mins 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
    13 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
    13 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
    13 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
    13 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
    13 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
    13 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
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
13 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
13 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
13 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
13 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
13 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

Why is a white electrical wire connected to 2 black wires?How to wire a light fixture with 3 white wires in box?How should I wire a ceiling fan when there's only three wires in the box?Two white, two black, two ground, and red wire in ceiling box connected to switchWhy is there a white wire connected to multiple black wires in my light box?How to wire a light with two white wires and one black wireReplace light switch connected to a power outlet with dimmer - two black wires to one black and redHow to wire a light with multiple black/white/green wires from the ceiling?Ceiling box has 2 black and white wires but fan/ light only has 1 of eachWhy neutral wire connected to load wire?Switch with 2 black, 2 white, 2 ground and 1 red wire connected to ceiling light and a receptacle?

कुँवर स्रोत दिक्चालन सूची"कुँवर""राणा कुँवरके वंशावली"

सि.चक भराडी, कोश्याँकुटोली तहसील इन्हें भी देखें बाहरी कड़ियाँ दिक्चालन सूची(निर्देशांक ढूँढें)www.uttara.gov.inउत्तराखण्ड - भारत सरकार के आधिकारिक पोर्टल परउत्तराखण्ड सरकार का आधिकारिक जालपृष्ठउत्तराखण्डउत्तरा कृषि प्रभासंबढ़ाने मेंसं