Get HOUR from AT TIME ZONE - sql

My DB is in Azure. I need my local (Israel) time.
SELECT GETDATE() AT TIME ZONE 'Israel Standard Time',
DATEPART(HOUR,(GETDATE() AT TIME ZONE 'Israel Standard Time'))
returns 13:
(No column name) (No column name)
2018-12-07 13:43:34.893 +02:00 13
I need it to return 15, since it's 13 (+2)=15
I want to do it without adding 2 hard-coded.

Try this:
SELECT GETDATE() AT TIME ZONE 'Israel Standard Time'
,DATEPART(HOUR,(GETDATE() AT TIME ZONE 'Israel Standard Time'))
,DATEPART(HOUR,(CONVERT(DATETIMEOFFSET, GETDATE(), 121) AT TIME ZONE 'Israel Standard Time'))

Related

How to retrieve User-defined Timezone's Localtime using sys.time_zone_info

The application allows users to define their time zone
screenshot.
But in SQL Server, time_zone_info is not the timezone selected by user.
So how could we map/relate the user defined time zone with the system table (which cater for DST)
By leverage on sys.time_zone_info, how can we write the SQL to take DST into consideration?
e.g. 20 Mar - 30 Jun 2021: Due to DST, SQL should auto move 1 hr
forward (SQL will smartly push 1 hr forward); 1st Jul onwards: the same
SQL will push 1 hr backward
here is the SQL i use (but user are not selecting these timezone options, but rather (UTC+7 Beijing Time..)
declare #utc_date datetime = getdate()
select #utc_date as utc_time_zone,
getdate() at time zone 'US Eastern Standard Time' as time_zone_est,
GETUTCDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time' as x,
CONVERT(DATETIME2(0), getdate(), 126) AT TIME ZONE 'Central European Standard Time'
;

Combining date and UTC time fields in Postgres

I have 2 separate fields for date and time. The time field is stored in UTC time. How can I combine the 2 into a datetime field into local time
Example:
date: 2021-03-08
time in UTC: 23:00
time zone: GMT+8
I would like to get 2021-03-08 07:00 in local time
or even 2021-03-07 23:00 in UTC
Note: Combining the fields is not an option unfortunately.
Need to know your time zone to convert. To convert utc to america/los_angeles time zone:
select '2021-03-08 23:00'::timestamp at time zone 'UTC' at time zone 'america/los_angeles'
you can check out below codes:
If you have a timestamp without time zone column and you're storing timestamps as UTC, you need to tell PostgreSQL that, and then tell it to convert it to your local time zone.
select created_at at time zone 'utc' at time zone 'america/los_angeles'
from users;
To be more concise, you can also use the abbreviation for the time zone:
select created_at at time zone 'utc' at time zone 'pst'
from users;
To see the list of time zones PostgreSQL supports:
select * from pg_timezone_names;
SInce the time difference is 8 hours, try
SELECT '2021-03-08'::date + ('23:00'::time + '8 hours'::interval);
If you want this to work with arbitrary time zones, the query becomes more complicated:
SELECT '2021-03-08'::date
+ ((current_date + '23:00'::time)
AT TIME ZONE 'UTC'
AT TIME ZONE 'Asia/Ulaanbaatar'
)::time;

DateTime conversion and comparison in SQL Query

I have a sql query for pulling a report from a table. The idea is to pull the sum of counts, grouped by day of the week, in the local timezone. Dates in the table are stored in UTC.
SELECT (SUM(t.di1) + SUM(t.di2) + SUM(t.di3) + SUM(t.di4)) AS [ScanCount],
DATEPART(WEEKDAY, t.LocalTime) AS [weekday]
FROM (SELECT di1,
di2,
di3,
di4,
CreatedOnUTC AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' AS LocalTime
FROM tableName
WHERE DeviceId = 649754) t
WHERE t.LocalTime > '03/16/2020 00:00'
AND t.LocalTime < '03/16/2020 23:59:59'
GROUP BY DATEPART(WEEKDAY, t.LocalTime)
ORDER BY DATEPART(WEEKDAY, t.LocalTime);
A query like this should only return a single day of the week count, but it returns 2 days. This obviously has something to do with the difference in time zones, whereas the UTC time contains dates from both 3/15 and 3/16. It seems that the conversion from UTC to Pacific Time works in the output but the UTC values are used in the where clause. How can I do this comparison to the new converted datetimes and not to the original UTC times?
Comparison between datetimeoffset and string literal works in UTC.
Simplest solution will be to convert datetimeoffset to datetime2.
Modify your inner query to:
cast(CreatedOnUTC AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' as datetime2(0)) AS LocalTime

Calculate time at specific Timezone, from UTC Time

I want to calculate Datetime at given timezone based on Datetime in UTC.
I thought that I can do it with the following:
DECLARE #timeUTC DATETIME = '2019-01-01 10:00:00'
SELECT
#timeUTC AS timeUTC,
#timeUTC AT TIME ZONE 'Central European Standard Time' as at_time_zone_offset,
CONVERT(datetime, #timeUTC AT TIME ZONE 'Central European Standard Time',1) at_timezone_convert
-- OUTPUT
---timeUTC |at_time_zone_offset |at_timezone_convert
---2019-01-01 10:00:00.000 |2019-01-01 10:00:00.000 +01:00 |2019-01-01 09:00:00.000
The problem is that result of at_timezone_convert is incorrect- when at UTC time is 10:00, then time +1 is 11:00, not 9.
How can I get the result to be 2019-01-01 11:00:00.000?
At time zone documentation clearly states:
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.
(emphasis mine)
If you'll declare #timeUTC as DateTimeOffset and not as DateTime you'll get different results - also, note that once you've converted the DateTimeOffset back to DateTime you'll get funky results.
Also, please note that the yyyy-mm-dd hh:mm:ss string representation format is a localized format when working with DateTime - that is not the case with the newer DateTime2 data type, which is one more reason why you should never work with DateTime again.
See a demo on DB<>Fiddle
Here's a trick I use from time to time:
DECLARE #timeUTC DATETIME = '2019-01-01 10:00:00'
SELECT #timeUTC
AS timeUTC, #timeUTC
AT TIME ZONE 'UTC'
AT TIME ZONE 'Central European Standard Time'
as at_time_zone_offset
Why does this work? Your original datetime has no offset information attached to it (other posters here have explained what the default is when this is the case) The first at time zone clause tells SQL Server "this datetime represents a time in UTC" and outputs a datetimeoffset data type. The second at time zone clause then tells it to convert it to your desired time zone.
Supplying the input as a datetimeoffset the AT TIME ZONE hint will convert to the input to the target time zone.
The snippet below is a simple example:
DECLARE #Utc DATETIME = '2019-01-01 10:00:00';
DECLARE #UtcOffset datetimeoffset(7) = #Utc;
SELECT
#Utc Utc,
#UtcOffset UtcOffset,
#UtcOffset AT TIME ZONE 'Central European Standard Time' UtcConverted;
-- Results
-- Utc 1/1/2019 10:00:00 AM
-- UtcOffset 1/1/2019 10:00:00 AM +00:00
-- UtcConverted 1/1/2019 11:00:00 AM +01:00
Zohar Peled explained it just fine, but just in case, here is a code example:
DECLARE #timeUTC DATETIME = '2019-01-01 10:00:00';
SELECT
#timeUTC AS timeUTC,
#timeUTC AT TIME ZONE 'Central European Standard Time' as at_time_zone_offset,
CONVERT(datetime, cast (#timeUTC AT TIME ZONE 'Central European Standard Time' as datetimeoffset),1) at_timezone_convert,
CAST(CAST(#timeUTC AS datetimeoffset) AT TIME ZONE 'Central European Standard Time' AS datetime) AS ResultYouNeeded;

SQL Server AT TIME ZONE

Using AT TIME ZONE is there a way to get my UTC Time without the 00:00 AT The end without using a LEFT in my query.
im doing this:
SELECT GETDATE() AT TIME ZONE 'EASTERN standard time' at time zone 'UTC'
Answer: 2018-03-05 15:08:00.930 +00:00
and trying to see if there is a better way other than doing
SELECT LEFT(GETDATE() AT TIME ZONE 'EASTERN standard time' at time zone 'UTC',23)
I would say declare it as variable and get datetime info from the datetimeoffset
Convert to datetime will do the trick
DECLARE #MyUtctime DATETIMEOFFSET
SET #MyUtctime = (
SELECT getdate() AT TIME ZONE 'EASTERN standard time' at TIME zone 'UTC'
)
SELECT CONVERT(DATETIME, #MyUtctime, 1)
SELECT getdate()
The following code will output your desired results:
CONVERT(VARCHAR, CONVERT(DATETIME, <DateField> AT TIME ZONE 'Eastern Standard Time' AT TIME ZONE 'UTC'), 100) AS [LocalDateTime]
If your EST date was '2018-03-22 22:48:24.893' the output UTC date would be 'Mar 22 2018 2:48AM'.