I have a SQL table with a column of varchar datatype that contains dates in timestamp format.
AccessId Date ComputerName NumberOfTries
-------------------------------------------------------------
1 132926085611026702 TESTE 1
When I use the command
[datetime]::FromFileTime('132926085611026702')
in PowerShell, I can get properly the data:
Thursday, March 3, 2022 4:03:42 PM
But I would like to know how I do this direct conversion through SQL to use in Power BI
Given that DateTime.FromFileTime(Int64) handles 1601-01-01 00:00:00Z-based values....
A Windows file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC).
...then you need to use CONVERT( bigint, "Date" ), and then pass that into DATEADD with nanosecond and '1601-01-01 00:00:00':
SELECT
DATEADD( nanosecond, CONVERT( bigint, "Date" ), CONVERT( datetime2(7), '1601-01-01 00:00:00' ) )
FROM
myTable
Related
I'm trying to bulk edit a datetime column on some records, leaving the time alone and only adjusting the date. The below code works unless the time is > 1800. When the record's time is > 1800, the updated date is 1 day less than desired (Wed, 27 Jan 2021 14:25:26 CST -06:00 becomes Wed, 26 Jan 2021 14:25:26 CST -06:00). We're in Central Time (Dallas, TX), so I'd assume it's an issue with timezones, and I think the issue is happening in the process of structuring the new datetime.
I've tried this with DATETIMEFROMPARTS and the 2 options below. Same issue every time.
This is in a Rails 5 app with sql server for the db. target_date is formatted yyyy-mm-dd.
products_relation.update_all("
date_column = DATEADD(
day,
DATEDIFF(dd, date_column, '#{target_date}'),
date_column
)
")
products_relation.update_all("
date_column = CONVERT(
datetime,
CONCAT('#{target_date}', ' ', CONVERT(CHAR(8), date_column, 108))
)
")
I am storing UTC datetime in Database
e.g.
2018-06-05 11:37:00.000 (UTC)
2018-06-05 17:07 (+5:30 India standart time)
I am having offset as :
offset as +02:00
How can I compare in sql query that now offset time matched ?
e.g.
2018-06-05 13:37:00.000
My issue is X (IST) date time converted to UTC and now I want to covert to different time zone (Y)
The following functions helped me to resolve the issue:
1. SWITCHOFFSET
2. TODATETIMEOFFSET
SELECT GETDATE()
SELECT SWITCHOFFSET(GETDATE(), '+05:30')
SELECT CONVERT(VARCHAR(19), SWITCHOFFSET(TODATETIMEOFFSET(GETDATE(), '+05:30'),'+00:00'), 120)
SELECT GETUTCDATE()
If I understand your question correctly, you can use the DATEADD function to calculate the new datetime based on the UTC datetime and the offset
For example:
2 hours = 120 minutes
DATEADD(minute, 120, '2018-06-05 11:37:00.000')
Or using hours
DATEADD(hour, 2, '2018-06-05 11:37:00.000')
You can also go the other way using negative numbers
You don't have to use a literal value, you can supply a column name to parameter 3 for use in a query and also use this expression as part of a where clause
Here's a cheat sheet for the DATEADD function:
https://learn.microsoft.com/en-us/sql/t-sql/functions/dateadd-transact-sql?view=sql-server-2017
This question is a follow up from this question.
I have a UTC time column and I want convert to into current local time (Central Time Zone or America/Chicago). I tried to use the function from #Ron Smith's answer, which is [dbo].[fn_UTC_to_DST] function.
In that function, it needs two arguments such as UTC time and offset. I input both like this,
SELECT dbo.fn_UTC_to_DST([time(UTC)],5) as Date
FROM tbl
Since we are in Day Light Saving time, I am using 5 as my offset. My output looks like this,
2017-09-27 20:55:00.000
2017-09-27 20:56:00.000
2017-09-27 20:57:00.000
2017-09-27 20:58:00.000
...
Which should be (central time),
2017-09-27 09:55:00.000
2017-09-27 09:56:00.000
2017-09-27 09:57:00.000
2017-09-27 09:58:00.000
...
So, I changed #Ron Smith's function like this,
CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
#UTC datetime,
#StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare
#DST datetime,
#SSM datetime, -- Second Sunday in March
#FSN datetime -- First Sunday in November
-- get DST Range
set #SSM = datename(year,#UTC) + '0314'
set #SSM = dateadd(hour,-5,dateadd(day,datepart(dw,#SSM)*-1+1,#SSM)) -- Changed from 2 to -5
set #FSN = datename(year,#UTC) + '1107'
set #FSN = dateadd(second,-6,dateadd(hour,2,dateadd(day,datepart(dw,#FSN)*-1+1,#FSN))) -- changed from 1 to -6
-- add an hour to #StandardOffset if #UTC is in DST range
if #UTC between #SSM and #FSN
set #StandardOffset = #StandardOffset + 1
-- convert to DST
set #DST = dateadd(hour,#StandardOffset,#UTC)
-- return converted datetime
return #DST
END
GO
However, this still gives me the same result as above.
1. What should I change for Central time?
2. Is there a way to automatically change to -5 during daylight saving time and -6 during standard time?
EDIT:
After looking at the Answer and the reference link from #Siyual,I created the dbo.TZCalendar table and I tried to create a function like this (takes one argument and returns a date from refrence link)
CREATE FUNCTION dbo.ConvertUTCToLocal
(
#utc DATETIME
)
RETURNS Datetime
AS BEGIN
SELECT UTCToLocal = DATEADD(HOUR, CASE
-- within Daylight Savings Time
WHEN #utc >= UTC_DST_Start AND #utc < UTC_DST_End
THEN -5
-- within Standard Time
ELSE -6 END, #utc)
FROM dbo.TZCalendar
WHERE CONVERT(DATE,#utc) >= [Year]
AND CONVERT(DATE,#utc) < DATEADD(YEAR, 1, [Year])
END
GO
This, does not work. The logic seems right for me, but, I just need a function without SCHEMABINDING (which is done in the reference link). How can I do that?
If you're using SQL Server 2016+ (or Azure SQL Database) this is built in:
SELECT YourInputDatetimeInUTC AT TIME ZONE 'UTC' AT TIME ZONE 'Central Standard Time'
The first one asserts your input is UTC, the second one converts it to US Central time, inclusive of DST when applicable (using a Windows time zone identifier).
However, since you said SQL 2012, I'll recommend my SQL Server Time Zone Support project, where this is a single operation and uses IANA identifiers:
SELECT Tzdb.UtcToLocal(YourInputDatetimeInUTC, 'America/Chicago')
The linked answer (Sql Server Specify time in another timezone) will get you most of the way there, but to answer the rest of your question, you'll have to make some modifications.
Firstly, I would create a DST calendar, since the DST start and end dates are something that we can compute:
CREATE TABLE dbo.TZCalendar
(
Year Int PRIMARY KEY,
UTC_DST_Start SMALLDATETIME NOT NULL,
UTC_DST_End SMALLDATETIME NOT NULL
);
SET DATEFIRST 7;
;WITH cte(d,p) AS
(
-- all the years from 2000 through 50 years after the current year:
SELECT TOP (YEAR(GETDATE())-2000+51) DATEADD(YEAR,number,'20000101'),
CASE WHEN number < 7 THEN 1 ELSE 0 END -- year < 2007 = 1, else 0
FROM [master].dbo.spt_values WHERE [type] = N'P' ORDER BY number
)
INSERT dbo.TZCalendar([Year],UTC_DST_Start,UTC_DST_End)
SELECT Year(d),
-- First Sunday in April (< 2007) or second Sunday in March (>= 2007):
DATEADD(HOUR, 7, DATEADD(DAY,(7-DATEPART(WEEKDAY,DATEADD(MONTH,2+p,d))+1)%7
+(7*ABS(p-1)),DATEADD(MONTH,2+p,d))),
-- Last Sunday in October (< 2007) or first Sunday in November (>= 2007):
DATEADD(HOUR, 6, DATEADD(DAY,(7-DATEPART(WEEKDAY,DATEADD(MONTH,10,d))+1)%7
-(7*p),DATEADD(MONTH,10,d)))
FROM cte
ORDER BY d;
This will generate the DST times from the year 2000 to 2067 (this can be expanded based on your needs).
Next, I would create a function to take a DATE in UTC and return the value in either CST or CDT, depending on the time of the year.
Create Function dbo.fnConvertUTCToCT(#UTC DateTime)
Returns DateTime
As Begin
Declare #Offset Int = 0
Select #Offset = Case When #UTC Between UTC_DST_Start And UTC_DST_End Then -5 Else -6 End
From dbo.TZCalendar
Where Year = Year(#UTC)
Set #UTC = DateAdd(Hour, #Offset, #UTC)
Return #UTC
End
Then you can just call that function with any time specified and get the CST or CDT translation returned:
Select dbo.fnConvertUTCToCT(GetUTCDate())
2017-09-27 12:24:26.377
UTC time to Central time including DST adjustments
This SQL expression converts UTC time to Central Standard time which also adjusts itself for the Day Light Saving Time period.
DATEADD(HOUR,datediff(HOUR,[HTMPOSTEDDATETIME] at time zone 'Central Standard Time',[HTMPOSTEDDATETIME]),[HTMPOSTEDDATETIME]) [JNL Posted Date]
My application needs to collect "Tuesday's" purchases for all locations world wide, where "Tueday" is the location's Tuesday (regardless of time zone). And if the user needs to re-run the report next week, I need to still get "Last Tuesday's" data. All of our data is stored using DateTimeOffset.
So
9/4/12 00:00:00 -7 through 9/4/12 23:59:59 -7
must MATCH
9/4/12 00:00:00 +11 through 9/4/12 23:59:59 +11
when I am executing my WHERE clause.
I can't convert to UTC in the WHERE clause because that will pick up the data for "Tuesday" in London (depending on DST), not the location's Tuesday.
I tried converting from DateTimeOffset to DateTime, but that seems to convert to UTC. (In my tests, passing 9/1/12 through 9/30/12 picked up 8/31/12 data.)
Is there a trick to doing something like this with TSQL?
Thanks!
IMHO
DateTimeOffset = DateTime+Offset(from UTC)
So your data is already representing Client's Local date and time. Just cast it to DateTime and you will get the client's local Date and time.
But in-case if you want to add the Offset to the datetime and want the resultant Datetime then
DECLARE #PurchaseDate DATETIMEOFFSET(7) = CAST('2007-05-08 12:30:29.1234567 +5:00' AS datetimeoffset(7))
SELECT CAST(SWITCHOFFSET (#PurchaseDate , '+00:00') AS DATETIME)
have a look at this blog for further info.
http://blogs.msdn.com/b/bartd/archive/2009/03/31/the-death-of-datetime.aspx
When casting a DATETIMEOFFSET as DATETIME it takes the date and time as offset in the value and simply drops the time zone. The same is true when casting as DATE or TIME. So, I think you can simply cast the column as DATE and compare that to the date-only value you wish to match:
DECLARE #targetDate DATETIME2 = '2012-09-04' --Or we could use DATE here
SELECT [PurchaseId], [PurchaseTime], CAST([PurchaseTime] AS DATE) AS "PurchaseDate"
FROM [Purchases]
WHERE CAST([PurchaseTime] AS DATE) = #targetDate
I'm not sure how efficient this will be (hopefully not bad if the provider is truly clever--which SQL Server likely would be), but you might improve it by bounding the original column value as well:
DECLARE #targetDate DATETIME2 = '2012-09-04' --DATETIME2 so we can adjust by hours
SELECT [PurchaseId], [PurchaseTime], CAST([PurchaseTime] AS DATE) AS "PurchaseDate"
FROM [Purchases]
WHERE CAST([PurchaseTime] AS DATE) = #targetDate --Keep only the local-date matches
AND [PurchaseTime] >= DATEADD(hh, -14, #targetDate) --Up to 14-hour time zone offset
AND [PurchaseTime] <= DATEADD(hh, 38, #targetDate) --24 hours later plus 14
This should efficiently index down to the set of possibilities and then filter properly on the conversion to the local date. Note that time zone offsets can be up to 14 hours (New Zealand is furthest I know at +13:00, but they can go to +/- 14:00 according to MSDN) and the #targetDate will be at the start of the day, so it compares back to 14 hours earlier and 24+14=38 hours later. DATETIME2 has the same range and precision as DATETIMEOFFSET, so it's better for this purpose than the original DATETIME (but it may also work okay with DATETIME instead).
I would like to convert getdate() in SQL Server to EST time.
UPDATED ANSWER (05-29-2020)
The Azure SQL team has released a new function which makes this even easier. SELECT CURRENT_TIMEZONE_ID() will return your server's timezone. Adding this function into the ORIGINAL ANSWER below yields a single query will work globally on all Azure SQL Servers.
SELECT CONVERT(DATETIME,GETDATE() AT TIME ZONE (SELECT CURRENT_TIMEZONE_ID()) AT TIME ZONE 'Eastern Standard Time')
This query will work on any Azure SQL Server.
ORIGINAL ANSWER:
There are a lot of answers here that are unnecessarily complex, or that don't account for daylight savings time. No massive CASE statements needed. No new stored procedure, or scalar/user defined functions are needed. As of SQL Server 2016, converting between timezones can be done with a single line of native sql. This has advantages. For example, it can be called from reports or used on databases that are read-only.
SELECT CONVERT(DATETIME,GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time')
That's it. Above, we are using the AT TIME ZONE features, described in more detail here. There may be some functions and features that are new here, so an explanation is warranted. The query above calls GETDATE() and sets it's timezone as UTC using AT TIMEZONE. Implicitly, this is also changing it's datatype from a datetime to datetimeoffset. Next, we'll call AT TIMEZONE again to cut it over to EST. Lastly, we'll wrap the entire thing in CONVERT() to get it back to a datetime, dropping the unneeded +/- hours portion during the process.
Taking the query step-by-step ...
SELECT [GetDate] = GETDATE()
SELECT [GetDateAtUtc] = GETDATE() AT TIME ZONE 'UTC'
SELECT [GetDateAtUtcAtEst] = GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'
SELECT [GetDateEst] = CONVERT(DATETIME,GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time')
Have you considered GETUTCDATE() and performing the offset from there?
If you mean EST as in standard time, then that is UTC-5, so
select dateadd(hour,-5,GETUTCDATE())
SQL server itself has the table current_utc_offset with correct offset for summer and winter time.
Please, try the query select * from current_utc_offset, change the date to different season on your server and review the table again.
So the correct function to get EST would be:
CREATE FUNCTION [dbo].[Getestlocaldatetime] ()
returns DATETIME
AS
BEGIN
DECLARE #zz NVARCHAR(12);
DECLARE #hh NVARCHAR(3);
DECLARE #dd DATETIME;
SET #zz = (SELECT current_utc_offset
FROM sys.time_zone_info
WHERE NAME = N'US Eastern Standard Time')
SET #hh = Substring(#zz, 1, 3);
SET #dd = Dateadd(hh, CONVERT(INT, #hh), Getutcdate())
RETURN #dd
END
EST is GMT-5 hours while EDT is GMT-4 hours.
To get EST:
select dateadd(hour,-5,GETUTCDATE())
To get EDT :
select dateadd(hour,-4,GETUTCDATE())
SELECT CONVERT(VARCHAR, CONVERT(DATETIME, GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'), 100) AS [Date_Result]
https://stackoverflow.com/a/49449695/6559330
using GETDATE() :
GMT :
DATE WILL BE DISPLAYED:
SELECT GETDATE()
EST :
USE GETDATE() FOR CONVERSION NOW:
SELECT DATEADD(HOUR, -4, CONVERT(varchar(20),GETDATE(),120))
If you are attempting to output a local time, such as eastern time, with Daylight savings time, you need a function that Detects the start and end of daylight savings time and then applies a variable offset: I've found this: http://joeyiodice.com/convert-sql-azure-getdate-utc-time-to-local-time/ useful.
GetDate() is the system time from the server itself.
Take the hour difference of the GetDate() now and the time it is now in EST use this code where 1 is that said difference ( in this instance the server is in Central Time zone) (This is also assuming your server is accounting for DST)
SELECT Dateadd(hour, 1, Getdate()) AS EST
For those who are using latest version of sql server can create a .net function
A scalar-valued function (SVF) returns a single value, such as a string, integer, or bit value. You can create scalar-valued user-defined functions in managed code using any .NET Framework programming language. These functions are accessible to Transact-SQL or other managed code. For information about the advantages of CLR integration and choosing between managed code and Transact-SQL.
Since .NET has access to all time zone at operating system so you don't have to calculate daylight saving -4 or -5 fundamentals.
var timeUtc = DateTime.UtcNow;
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime easternTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, easternZone);
Select CONVERT(DATETIME,GETUTCDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time')
If you want to do this without calling a function, you can do it with a CASE statement as well. The code below converts a UTC field to Mountain Time accounting for daylight savings. For EST, you would just change all the -6 to -4 and change all the -7 to -5.
--Adjust a UTC value, in the example the UTC field is identified as UTC.Field, to account for daylight savings time when converting out of UTC to Mountain time.
CASE
--When it's between March and November, it is summer time which is -6 from UTC
WHEN MONTH ( UTC.Field ) > 3 AND MONTH ( UTC.Field ) < 11
THEN DATEADD ( HOUR , -6 , UTC.Field )
--When its March and the day is greater than the 14, you know it's summer (-6)
WHEN MONTH ( UTC.Field ) = 3
AND DATEPART ( DAY , UTC.Field ) >= 14
THEN
--However, if UTC is before 9am on that Sunday, then it's before 2am Mountain which means it's still Winter daylight time.
CASE
WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1
AND UTC.Field < '9:00'
--Before 2am mountain time so it's winter, -7 hours for Winter daylight time
THEN DATEADD ( HOUR , -7 , UTC.Field )
--Otherwise -6 because it'll be after 2am making it Summer daylight time
ELSE DATEADD ( HOUR , -6 , UTC.Field )
END
WHEN MONTH ( UTC.Field ) = 3
AND ( DATEPART ( WEEKDAY , UTC.Field ) + 7 ) <= DATEPART ( day , UTC.Field )
THEN
--According to the date, it's moved onto Summer daylight, but we need to account for the hours leading up to 2am if it's Sunday
CASE
WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1
AND UTC.Field < '9:00'
--Before 9am UTC is before 2am Mountain so it's winter Daylight, -7 hours
THEN DATEADD ( HOUR , -7 , UTC.Field )
--Otherwise, it's summer daylight, -6 hours
ELSE DATEADD ( HOUR , -6 , UTC.Field )
END
--When it's November and the weekday is greater than the calendar date, it's still Summer so -6 from the time
WHEN MONTH ( UTC.Field ) = 11
AND DATEPART ( WEEKDAY , UTC.Field ) > DATEPART ( DAY , UTC.Field )
THEN DATEADD ( HOUR , -6 , UTC.Field )
WHEN MONTH ( UTC.Field ) = 11
AND DATEPART ( WEEKDAY , UTC.Field ) <= DATEPART ( DAY , UTC.Field )
--If the weekday is less than or equal to the calendar day it's Winter daylight but we need to account for the hours leading up to 2am.
CASE
WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1
AND UTC.Field < '8:00'
--If it's before 8am UTC and it's Sunday in the logic outlined, then it's still Summer daylight, -6 hours
THEN DATEADD ( HOUR , -6 , UTC.Field )
--Otherwise, adjust for Winter daylight at -7
ELSE DATEADD ( HOUR , -7 , UTC.Field )
END
--If the date doesn't fall into any of the above logic, it's Winter daylight, -7
ELSE
DATEADD ( HOUR , -7 , UTC.Field )
END