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
$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
sql datetime t-sql
New contributor
$endgroup$
|
show 1 more comment
$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
sql datetime t-sql
New contributor
$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
|
show 1 more comment
$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
sql datetime t-sql
New contributor
$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
sql datetime t-sql
New contributor
New contributor
edited 1 min ago
Jamal♦
30.4k11121227
30.4k11121227
New contributor
asked 14 hours ago
QuandaryQuandary
1013
1013
New contributor
New contributor
$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
|
show 1 more comment
$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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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.
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$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