I have a messy table that was filled with events that sometimes got a DateTime, and in other places got a DateTimeOffset assigned to the Date field, similar to this (provided you live far enough outside the Divided Kingdom's longitude):
DECLARE @MY_LOG TABLE ([MOMENT] DATETIMEOFFSET, [PAYLOAD] NVARCHAR(200));
INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (GETDATE(),'first entry')
WAITFOR DELAY '00:00:00.100';
INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (SYSDATETIMEOFFSET(),'second entry')
WAITFOR DELAY '00:00:00.100';
INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (GETDATE(),'third entry')
WAITFOR DELAY '00:00:00.100';
INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (SYSDATETIMEOFFSET(),'forth entry')
SELECT [MOMENT],[PAYLOAD] FROM @MY_LOG ORDER BY [MOMENT] ASC;
The result of the last select would be this example:
2020-03-31 02:39:10.6779279 +02:00 second entry
2020-03-31 02:39:10.8809259 +02:00 forth entry
2020-03-31 02:39:10.5730000 +00:00 first entry
2020-03-31 02:39:10.7770000 +00:00 third entry
I tried to fix it by using SWITCHOFFSET, which adds the missing offset, but also compensates for it:
SELECT [MOMENT],
[PAYLOAD],
CASE WHEN DATEPART(tz,[MOMENT])=0 THEN SWITCHOFFSET(MOMENT, '+02:00') ELSE MOMENT END AS FIXED
FROM @MY_LOG ORDER BY FIXED ASC;
The result is:
2020-03-31 02:39:10.6779279 +02:00 second entry 2020-03-31 02:39:10.6779279 +02:00
2020-03-31 02:39:10.8809259 +02:00 forth entry 2020-03-31 02:39:10.8809259 +02:00
2020-03-31 02:39:10.5730000 +00:00 first entry 2020-03-31 04:39:10.5730000 +02:00
2020-03-31 02:39:10.7770000 +00:00 third entry 2020-03-31 04:39:10.7770000 +02:00
I may also need to account for switching moments like in This question, but for now I'm looking for a non destructive (read-only) solution to order the rows by date