SQL time in incorrect from that of my system timezone - sql

We have a SQL database that returns all the times in Greenwich Mean Time (GMT). We are in the Eastern Standard Timezone (EST). This messes up some queries that we have that pull data from specific dates. I tried using the (StartTime AT TIME ZONE 'Eastern Standard Time' as StartTime_ET, but that only returns the result as same in GMT -5. I just want the exact result to be in EST .
This changes the complete logic process of mine. Is there any way to do that?

Assuming your values are all UTC and that your column StartTime is not a datetimeoffset, then you need to turn your value into a datetimeoffset first, and then change the time zone. When you use AT TIMEZONE on a date and time data type that isn't a DATETIMEOFFSET it is assumed that the value is already at the correct timezone. Therefore, for example something like SELECT GETUTCDATE() AT TIME ZONE 'Eastern Standard Time'; would return 2021-08-05 09:53:56.8500000 -04:00 right now, even though the time in EST is actually 2021-08-05 05:53:56.8500000 -04:00 right now.
As a result you need to add the offset first and then use AT TIME ZONE. So, with GETUTCDATE that would be like this:
SELECT SWITCHOFFSET(GETUTCDATE(),0) AT TIME ZONE 'Eastern Standard Time';
Therefore, presumably, you just need to do the same for your column, StartTime, which is also a UTC time:
SWITCHOFFSET(StartTime,0) AT TIME ZONE 'Eastern Standard Time'
If you don't want the timezone portion, then you can convert it back to a different date and time data type:
CONVERT(datetime2(0),SWITCHOFFSET(StartTime,0) AT TIME ZONE 'Eastern Standard Time')

Related

Add offset value to time in SQL Server

I felt like this should be easy but I'm not finding answer. The query below will give me the current date/time in California and represent it as UTC with a timezone offset (currently -08:00):
select getdate() at time zone 'Pacific Standard Time'
I simply want to apply the offset and get a timestamp showing the current local time and then drop the offset. I feel like there should be a way to achieve this without having to pick through it with string and date functions. For example, I want to go from
2021-11-24 18:03:41.190 -08:00
to
2021-11-24 10:03:41.190
Is there a succinct way to do this?
When you use AT TIME ZONE on a value that isn't a datetimeoffset it's assumed that the value is at the time zone you are converting it to.
Instead, therefore, you could nest the AT TIME ZONE clauses. If you did do this though, I would also suggest using SYSUTCDATE rather than GETDATE (which returns the local time to the host, which could be any timezone).
SELECT SYSUTCDATETIME() AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time';
Though really, just use SYSDATETIMEOFFSET to start with; then you just need one AT TIME ZONE as the RDBMS already knows what timezone the value is for.
SELECT SYSDATETIMEOFFSET() AT TIME ZONE 'Pacific Standard Time';
db<>fiddle
Declare #myDateTime datetime = '2021-11-24 21:35:25.984'; --UTC time
Select cast(#myDateTime At Time Zone 'UTC' At Time Zone 'Pacific Standard Time' As datetime);
Or - you can just apply the desired offset and convert back to datetime
Select cast(switchoffset(#myDateTime, '-08:00') As datetime)
The problem with using switchoffset is that it isn't DST aware and would need to be changed to use a different offset value. If you change the date above to October - the PST time would be 14:35:25.983 but the second calculation still returns 13:35:25.983

Reading and Writing UTC to TIMESTAMP in Postgresql

I have a Java application that inserts data into a database using prepared statements. In the preparedStamement date is set in UTC format.
preparedStatement.setDate(index, new java.sql.Date(date.getTime()), UTC);
I want to be sure that when read and write operations execute on the table, the response should ALWAYS be in UTC format. At the below query, when the data is read it will be converted to the client's timezone. I don't want TIME_COLUMN to be converted to any time zone. It should remain in the UTC time zone. How can I define TIME_COLUMN in that way?
Notes: I cannot edit the DB timezone. I cannot edit select queries using At time zone.
"TIME_COLUMN" TIMESTAMPTZ default (now() at time zone 'utc'),
You could set the timezone of your RDBMS to UTC, see https://medium.com/building-the-system/how-to-store-dates-and-times-in-postgresql-269bda8d6403
When that's done, whatever dates you store, they will be in UTC. Converting from UTC into something else can be done either in queries, like
select created_at at time zone 'utc' at time zone 'america/los_angeles'
from users;
Taken from https://popsql.com/learn-sql/postgresql/how-to-convert-utc-to-local-time-zone-in-postgresql
Or, you can convert the timezone at application level.

Is there an SQL function to convert the time zone to local time (LDT)?

I am quite new to SQL, and trying to pull a data table from the database (flight) using the following command:
select
flight.FLT_NBR,
flight.LEG_NBR,
flight.LEG_TAIL_NBR,
flight.LEG_IATA_ORIG_CD as FLT_SCHD_ORIG_ARPT_CD,
flight.LEG_IATA_DEST_CD as FLT_SCHD_DEST_ARPT_CD,
flight.SCHD_ARR_TMSTP as Scheduled_Arrival,
flight.ACTL_ARR_TMSTP AS Actual_Arrival,
flight.SCHD_DPRT_TMSTP as Scheduled_Departure,
flight.ACTL_DPRT_TMSTP AS Actual_Departure,
from home/tulips/FT_FLIGHT_LEG flight
Now the problem is there are multiple country origin and destination with different times. How do I incorporate same time zone for all the countries? I tried using the command as time zone 'UTC' such as below but it didn't work... May be I am adding it in a wrong place?
select
flight.FLT_NBR,
flight.LEG_NBR,
flight.LEG_TAIL_NBR,
flight.LEG_IATA_ORIG_CD as FLT_SCHD_ORIG_ARPT_CD,
flight.LEG_IATA_DEST_CD as FLT_SCHD_DEST_ARPT_CD,
flight.SCHD_ARR_TMSTP as Scheduled_Arrival as time zone 'UTC',
flight.ACTL_ARR_TMSTP AS Actual_Arrival as time zone 'UTC',
flight.SCHD_DPRT_TMSTP as Scheduled_Departure as time zone 'UTC',
flight.ACTL_DPRT_TMSTP AS Actual_Departure as time zone 'UTC',
from home/tulips/FT_FLIGHT_LEG flight
Please help me a way to have one time zone for all the Scheduled_Arrival,Actual_Arrival,Scheduled_Departure and Actual_Departure
The expression you want is at time zone, not as time zone.
In order to use it, you need to know what time zone the original datetime value represents. For example, I have a SQL server in Sydney Australia, so getdate() will return my local date and time. However, to convert it to UTC I must first inform SQL of the fact that the value starts off in AUS Eastern Standard Time, and then ask it to convert it to UTC, by chaining at time zone expressions together. Like this:
select getdate() at time zone 'AUS Eastern Standard Time' at time zone 'UTC'
If you don't know the time zone of the original datetime value, there is no way for SQL to know how to change it to a different time zone's value.

How to get the Time Offset converted to an Int or added to the datetime column (with TSQL)

I have the following script giving me:
Select ENDTIME_UTC AT TIME ZONE 'E. South America Standard Time' as TransactionDate_ESAST
,ENDTIME_UTC as TransactionDate
From Table_CYC
--Results: 2019-11-09 21:02:28.000 -03:00, 2019-11-09 21:02:28.000
However, I would want it either -3 (as an integer for just the offset portion) or 2019-11-09 18:02:28.000, where the hour is subtracted by three.
What would be the best way to go about this?
Thanks,
Yolanda
As currently written you are asserting that the existing value is in Brasilia time and not performing any time zone conversion. Instead, you need to assert that the existing value is in UTC and then convert to Brasilia time.
This is done by calling AT TIME ZONE twice.
SELECT ENDTIME_UTC AT TIME ZONE 'UTC' AT TIME ZONE 'E. South America Standard Time'
The first AT TIME ZONE creates a datetimeoffset from your input datetime asserting that it should be applied with the UTC time zone.
The second AT TIME ZONE then converts from that datetimeoffset to another datetimeoffset with the given time zone.
Note that this is only necessary because your original field is of type datetime (or datetime2, etc.). If instead your field was a datetimeoffset, then your original code would work fine.

Postgres SQL Timezone conversion

I could appreciate a second pair of eyes on my Postgres syntax.
Database stores timestamp in UTC. I'm trying to convert from UTC to Eastern Daylight Time EDT, but the output is not accurate.
Here's my syntax:
SELECT
to_char(((timestamp AT TIME ZONE 'UTC') AT TIME ZONE 'EDT'), 'MM/DD/YYYY HH24:MI')
FROM table_name
Record TimeStamp:
09/10/2016 12:00
Query Output:
09/10/2016 16:00
Desired Output:
09/10/2016 08:00
Thanks for your assistance.
Saying AT TIMEZONE twice is redundant since it will just convert from whatever the current timezone (which you suggest is UTC) to UTC then to EDT.
The fact that you feel the need to convert it to UTC tells me you're not storing it as a TIMESTAMP WITH TIMEZONE. Check if this is the case. If it is, that's likely your problem. From the docs:
If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system's timezone parameter, and is converted to UTC using the offset for the timezone zone.
Basically, if you don't specify, it assumes it's from your current timezone by default, not UTC. It's possible you entered a UTC timestamp and it assumed it was EDT.