Difference UTC and GETUTCDATE() - sql-server

I'm having this issue
select getDATE() AT TIME ZONE 'utc'
SELECT GETUTCDATE()
output:
2021-06-08 12:50:19.260 +00:00
2021-06-08 11:50:19.260
Why does this happen? Basicaly I want to convert to UTC but it adds one hour.
Current time in Portugal is now 12:50, so the first output should be 12:50

Firstly, to quote AT TIME ZONE (Transact-SQL):
Converts an inputdate to the corresponding datetimeoffset value in the target time zone. When inputdate is provided without offset information, the function applies the offset of the time zone assuming that inputdate is in the target time zone. If inputdate is provided as a datetimeoffset value, then AT TIME ZONE clause converts it into the target time zone using the time zone conversion rules.
GETDATE returns a datetime, it has no offset property. This means, per the quoted text above, it is assumed to be UTC when you set it the the UTC timezone. As you state you are in Portugal then you are currently UTC+1, and this means you (effectively) get a "UTC+1" UTC time.
GETUTCDATE, unsurprisingly, gives you the UTC time, and thus is correct.
If you want a datetimeoffset time with the current UTC time then use sysdatetimeoffset:
SELECT SYSDATETIMEOFFSET() AT TIME ZONE 'UTC';

This query:
select getDATE() AT TIME ZONE 'utc'
has two separate parts:
getDATE()
The documentation says:
Returns the current database system timestamp
AT TIME ZONE 'utc'
The documentation says:
Converts an inputdate to the corresponding datetimeoffset value in the target time zone. When inputdate is provided without offset information, the function applies the offset of the time zone assuming that inputdate is in the target time zone.
So the result from the local time is then double-adjusted again into the time zone offset
GETUTCDATE
This value represents the current UTC time (Coordinated Universal Time).
So if you used this with AT TIME ZONE 'UTC' then you would get the correct time

Related

How to insert UTC with Time Zone in sql

I have code in postgresql transform to sql server
In postgresql while inserting in table with data type timestamp with time zone in UTC format, it inserted with time zone
create table public.testt123 (tz timestamp with time zone)
insert into public.testt123
select now() at time zone 'utc'
select * from public.testt123
enter image description here
I have tried same with Sql server, below query
create table Test1(tz [datetimeoffset](7))
insert into Test1
select GETUTCDATE() AT TIME ZONE 'UTC'
enter image description here
It inserted without time zone, I have check using SYSDATETIMEOFFSET() but it gives time zone with current datetime not UTC
I have tried by left function, but it is correct way?
Select cast(left(SYSDATETIMEOFFSET() AT TIME ZONE 'UTC',28) + DATENAME(TZOFFSET, SYSDATETIMEOFFSET()) as [datetimeoffset](7))
enter image description here
Based on the comments, I suspect what you want is:
SELECT SYSUTCDATETIME() AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time';
Though this could be abbreviated to:
SELECT SYSDATETIMEOFFSET() AT TIME ZONE 'India Standard Time';
I have check using SYSDATETIMEOFFSET() but it gives time zone with
current datetime not UTC
Correct, SYSDATETIMEOFFSET() returns a datetimeoffset but with the current UTC offset of the database server. Specify AT TIME ZONE 'UTC' to get a datetimeoffset with the UTC time with a zero offset:
SYSDATETIMEOFFSET() AT TIME ZONE 'UTC'

SQL Server UTC to Local time 'at time zone' not offseting time

I am trying to convert from UTC to Eastern Standard Time. But the code below is not producing the result that I expect.
SELECT
GETUTCDATE() AS UTC_Date, --original datetime value
GETUTCDATE() AT TIME ZONE 'Eastern Standard Time' AS ETZ
The result is
UTC_Date = 2022-01-16 01:15:39.920
ETZ =2022-01-16 01:15:39.920 -05:00
How can I get a simple date time with the offset applied instead of just added on to the end of the string?

How to convert AT TIME ZONE return value to actual datetime value in SQL Server 2016?

I want to convert UTC value to Eastern Time Zone (any time zone) in SQL directly. I am trying below query but getting DATETIMEOFFSET.
I am trying to convert below UTC DateTime into Eastern time zone.
SELECT CONVERT(DATETIME,'2019-05-27 13:00:00' AT TIME ZONE 'Eastern Standard Time'
I am expecting output for above query is '2019-05-27 09:00:00' but the actual output is coming like '2019-05-27 13:00:00 -04:00'
you can do this
select CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, '2019-05-27 13:00:00'), DATEPART(TZOFFSET,
SYSDATETIMEOFFSET() AT TIME ZONE 'Eastern Standard Time')))
You're close. So far, you've told SQL Server the native time zone for the datetime that you've passed in. Now you need to tell it to convert it to something else. This should do the trick:
SELECT CONVERT(DATETIME,'2019-05-27 13:00:00')
AT TIME ZONE 'Eastern Standard Time'
AT TIME ZONE 'UTC';
This should give you something with the -00:00 offset. If you don't want that, cast the result back to a time zone-less datatype.

Convert UTC on Azure to EST Time (including Daylight saving Time-dynamic version)

I have a question about converting UTC time zone to EST time zone since I am still new to SQL language and Azure platform. In log file, I used system built-in function "GetDate()" in log file to get the Date/Time. However, while accessing Azure database on my SSMS, using system-built in function (GetDate()) gives me the datetime in UTC time zone, which is 4 hours ahead of Eastern Time Zone (EST). I have asked similar question before for converting UTC to EST here
, and #DanGuzman helped me fix my code. But this question is more about converting UTC to EST (considering Daylight saving time dynamically). Below is my code so far, and I used this link as a reference. However, I would like to make my code dynamic so that I can keep using it for 2020, 2021 as well.
Below code works ONLY for 2019 (since Daylight Saving starts on March 10,2019 until November 3, 2019. Within the date range, below code forward one hour of EST time during daylight saving time range.
CREATE FUNCTION [dbo].[EST_GetDateTime]
(
-- no parameter
)
RETURNS datetime
AS
BEGIN
DECLARE
#EST datetime,
#StandardOffset int,
#DST datetime, -- Daylight Saving Time
#SSM datetime, -- Second Sunday in March
#FSN datetime -- First Sunday in November
-- get DST Range
set #EST = CAST(DATEADD(hh,-5,GETDATE()) AS DATETIME)
set #StandardOffset = 0
set #SSM = datename(year,#EST) + '0310' -- Set which day daylight saving start (for 2019, March 10)
set #SSM = dateadd(hour,2,dateadd(day,datepart(dw,#SSM)*-1+1,#SSM))
set #FSN = datename(year,#EST) + '1103' -- Set which day daylight saving start (for 2019, March 10)
set #FSN = dateadd(second,-1,dateadd(hour,2,dateadd(day,datepart(dw,#FSN)*-1+1,#FSN)))
-- add an hour to #StandardOffset if #EST is in DST range
if #EST between #SSM and #FSN
set #StandardOffset = #StandardOffset + 1
-- convert to DST
set #EST = CAST(DATEADD(hh,-5+#StandardOffset ,GETDATE()) AS DATETIME)
RETURN #EST
END
GO
Can someone please give any suggestions how to improve my existing code (able to work dynamically) so that I do not need to change the function every single year for adjusting day light saving.
Since Azure SQL is ahead of the on-premises version, I think you can use the syntax select getutcdate() at time zone 'UTC' at time zone 'Eastern Standard Time'. Also, I'd switch to getutcdate() as that should be invariant regardless of the server's TZ. More information on at time zone here.
One method is a function that converts SYSDATETIMEOFFSET() to EST and converts the result to datetime:
CREATE FUNCTION dbo.EST_GetDateTime()
RETURNS datetime
AS
BEGIN
RETURN(SELECT CAST(SYSDATETIMEOFFSET() AT TIME ZONE 'Eastern Standard Time' AS datetime));
END
GO
--example usage
SELECT dbo.EST_GetDateTime();
GO
This should do exactly what you need.
SELECT CONVERT(DATETIME,GETDATE() AT TIME ZONE (SELECT CURRENT_TIMEZONE_ID()) AT TIME ZONE 'Eastern Standard Time')
Explanation: This gets the current datetime in the server's local timezone using CURRENT_TIMEZONE_ID(). We then use AT TIME ZONE to make it a datetimeoffset, then we cut that datetimeoffset over to requested timezone... here 'Eastern Standard Time'. Lastly the whole thing is wrapped in a CONVERT() to cut the datetimeoffset objects over to a proper datetime datatype.

(T-SQL) Did daylight savings occur in the last hour?

I have a process that is going to use table partitioning (each partition is 1 hour) and I need to handle the daylight savings flips when archiving out the data.
For instance, this past weekend it went from 1:59:59 to 1:00:00, so the second time that the partitioning code ran at 1:05am nothing would occur - the midnight hour had already been SWITCHed out.
However, when spring rolls around, the time goes from 1:59am to 3:00am, so when the job runs at 3:05, it would SWITCH out 2am.... leaving the data from the 1am hour in the original table.
In theory I can just look for the oldest not-current partition with data and flip that one (partition key is a default getdate() constraint), but I was wondering if there was some way to use AT TIME ZONE to determine that daylight savings had "occurred", so that we could have different code to handle that older hour still being out there.
Thanks.
Maybe something like this. Basically take your current getdate() and use AT TIME ZONE with any time zone that observes. Then use DATEPART tz and compare your current and before.
Regardless of what the server time zone is, using AT TIME ZONE will get you the offset for a particular datetime value in that time zone.
For comparison of before I think you'd need to use 2 hours, 1 for the switch and 1 for how far back you want to check.
Give this a look:
DECLARE #BeforeDate DATETIME = '2018-11-04 1:59' --Before the change
DECLARE #AfterDate DATETIME = '2018-11-04 3:00' --After the change
--use can use AT TIME ZONE with DATEPART tz which tells you offset in minutes
--I'm in central, any should work for any that observe the time change
--Your offset is different because of the change.
SELECT DATEPART(tz, #BeforeDate AT TIME ZONE 'Central Standard Time')
SELECT DATEPART(tz, #AfterDate AT TIME ZONE 'Central Standard Time')
--using the above you could possibly compare current offset to 2 hours prior to see if they changed. 2 hours, 1 for the switch and 1 for how far back you want to compare.
DECLARE #CurrentDate DATETIME = '2018-11-04 3:00' --"simulate" getdate() as of the time change
DECLARE #PriorOffSet INT = (SELECT DATEPART(tz, DATEADD(HOUR, -2, #CurrentDate) AT TIME ZONE 'Central Standard Time')) --You'd have to subtract 2 hours to account for the hour shift and the hour back you want to check.
DECLARE #CurrentOffset INT = (SELECT DATEPART(tz, #CurrentDate AT TIME ZONE 'Central Standard Time'))
SELECT #PriorOffSet, #CurrentOffset
IF #PriorOffSet <> #CurrentOffset
SELECT 'Time changed in the last hour'
ELSE
SELECT 'No time change in the last hour'

Resources