I have an insert proc that passes in GETDATE()
as one of the values because each insert also stores when it was inserted. This is hosted on SQL Azure - which uses GMT.
Now, when I am receiving messages, I have the GMT date stored for each of them in their timestamp columns, how do I convert this to the local datetime
for wherever you are when you are accessing my page?
Thanks.
You could do something like this:
declare @InputUtcDateTime datetime2 = '2011-05-20 06:30:18'
declare @LocalDateTime datetime2 = dateadd(minute, datepart(TZoffset, sysdatetimeoffset()), @InputUtcDateTime)
print @LocalDateTime
or
declare @InputUtcDateTime datetime2 = '2011-05-20 06:30:18'
declare @LocalDateTime datetime2 = dateadd(minute, datediff(minute, sysutcdatetime(), sysdatetime()), @InputUtcDateTime)
print @LocalDateTime
Aside from the Daylight Savings issue, why not simplify with:
yourDateTime - getutcdate() + getdate()
For MST as an example... considering each DTM is stored in GMT already, that simplifies things..
SWITCHOFFSET(CONVERT(DATETIMEOFFSET, [ColumnName]), '-07:00')
Now, if your local date/time is something other than GMT/UTC, you'll likely want to use the following...
SWITCHOFFSET(TODATETIMEOFFSET([ColumnName], datepart(tz,sysdatetimeoffset())),'+00:00')
Here's the breakdown.
SWITCHOFFSET
- converts a DateTimeOffset value to a different timezone, while preserving the offset.TODATETIMEOFFSET
- converts a DateTime value to a DateTimeOffset value at a specified timezone.DATEPART
- in this case is getting the timezone part of the local datetime.'+00:00'
- the target offset, in the second example is UTC/GMT target, from local... the former example is to MST.NOTE/WARNING: I don't believe that this accounts for Daylight Savings Time, which could be an issue for you. If absolute preservation isn't necessary, you may want to simply add a secondary column, with the rough conversion and go forward safely.
You may want to abstract the logic into a function call, in order to account for the preservation of DST... it shouldn't be excessively difficult to do, though.
CREATE FUNCTION [dbo].[fn_DateTime_GMTFromLocal](@LocalTime DATETIME)
RETURNS DATETIME2(3)
AS
BEGIN
/*
=============================================
Author: Mark Griffiths
Create date: 29/05/2018
Description: BST runs from 02:00AM on the last Sunday of March to the same time on the last Sunday of October.
The Series of DATEDIFFs and DATEADDS below function as follows
1 ● Count the number of months there have been between the given date and start of computer time
2 ● Add that number of months to the end of the first month to get the end of the given month
3 ● Count the number of days there have been between the end of the given month and the first Saturday
4 ● Add that number of days to the calculated end of the given month
5 ● Add Two hours to that time as the clocks go back at 02:00 in the morning
I know that the tabbing below makes it all look odd, but the description above is the best way I could find to comment things, given the nesting...
The comments in the code below should help find the nesting levels and the numbers refer to the bullet points above.
=============================================
-- Test Variables --
DECLARE @GMTime DATETIME2(3) = '2018-05-01 12:00:00.000'
*/
DECLARE @RealTime As DATETIME2(3)
DECLARE @Year VARCHAR(4)
SET @Year = CONVERT(VARCHAR,DATEPART(YEAR,@GMTime))
DECLARE @StartOfBST AS DATETIME
DECLARE @EndOfBST AS DATETIME
SELECT
@StartOfBST =
DATEADD -----------------------------------------------------------------------------------------
( -- |
HOUR -- |
,2 -- |
,DATEADD ----------------------------------------------------------------------------- |
( -- | |
DAY -- | |
,DATEDIFF ------------------------------------------------------------- | |
( -- | | |
DAY -- | | |
,'19000107' -- | | 5
,DATEADD --------------------------------------------- | | |
( -- | 3 4 |
MONTH -- | | | |
,DATEDIFF(MONTH,0,CONVERT(DATE,'03/01/' + @Year)) -- 1 2 | | |
,CONVERT(DATE,'01/31/1900') -- | | | |
) --------------------------------------------- | | |
)/7*7 ------------------------------------------------------------- | |
,'19000107' -- | |
) --------------------------------------------------------------------- |
), -----------------------------------------------------------------------------------------
@EndOfBST =
DATEADD(HOUR,2,DATEADD(day,DATEDIFF(day,'19000107',DATEADD(month,DATEDIFF(MONTH,0,CONVERT(DATE,'10/01/' + @Year)),30))/7*7,'19000107'))
SET @RealTime = CASE
WHEN @GMTime BETWEEN @StartOfBST AND @EndOfBST THEN DATEADD(HOUR,-1,@GMTime)
ELSE @GMTime
END
RETURN @RealTime;
--SELECT @RealTime
END
*EDIT: Changed CONVERT(DATE,'01/30/1900')
to CONVERT(DATE,'01/31/1900')
as since 45BC, January has had 31 days. This caused some times an incorrect result for 2019, and any others where the last Sunday in March is the 31st.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With