Postgres SQL Timezone conversion - sql

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.

Related

Timestamp string conversion / from_utc_timestamp

I need to convert 2021-10-03 15:10:00.0 as 2021-10-03T15:10:00-04:00
I tried with.
from_utc_timestamp(from_unixtime(unix_timestamp('2021-10-03 15:10:00.0', "yyyy-MM-dd HH:mm:ss.S"),"yyyy-MM-dd'T'HH:mm:ssXXX"),"America/New_York")
I got Null value
Any suggestions please
from_utc_timestamp can accept timestamp or compatible string (yyyy-MM-dd HH:mm:ss.S), or bigint, not this: "yyyy-MM-dd'T'HH:mm:ssXXX"
Hive timestamps are timezoneless. Once you converted from UTC to America/NY, the timezone information is lost, only you know in which timezone it is, having timestamp converted it is already impossible to derive the timezone from it.
You can concatenate with timezone, conversion like this returns what you need but it works for particular date only. In December -05:00 timezone should be usedm not +04:00:
date_format(from_utc_timestamp('2021-10-03 15:10:00.0',"America/New_York"),"yyyy-MM-dd'T'HH:mm:ss+04:00") --This is wrong!!!
From_utc_timestamp is Daylight saving aware. It can be -05:00 or -04:00 depending on the date.
Consider this example, first returns 5, second returns 4:
select (unix_timestamp("2020-01-01 12:00:00.0")-unix_timestamp(from_utc_timestamp("2020-01-01 12:00:00.0","America/New_York")))/60/60
select (unix_timestamp("2020-10-19 12:00:00.0")-unix_timestamp(from_utc_timestamp("2020-10-19 12:00:00.0","America/New_York")))/60/60
So, you can get current time zone corresponding to America/New_York for the same timestamp and concatenate it with converted timestamp:
select concat(date_format(from_utc_timestamp('2021-10-03 15:10:00.0',"America/New_York"),"yyyy-MM-dd'T'HH:mm:ss"),'+0',
--get hrs shift
(unix_timestamp("2021-10-03 15:10:00.0")-unix_timestamp(from_utc_timestamp("2021-10-03 15:10:00.0","America/New_York"))) div 3600,':00')
Result:
2021-10-03T11:10:00+04:00
It should work correctly with different timestamps taking into account daylight saving time for America/New_York.

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.

SQL time in incorrect from that of my system timezone

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')

Remove UTC from a TIMESTAMP field in SQL(BigQuery)

I have been able to convert a TIMESTAMP field that is in UTC to CST using:
SELECT
TIMESTAMP(started_at) AS UTC,
TIMESTAMP_SUB(TIMESTAMP (started_at), INTERVAL 5 HOUR) AS CST
This returns:
ROW
UTC
CST
1
2020-05-17 13:07:22 UTC
2020-05-17 08:07:22 UTC
The second TIMESTAMP displays the correct date and time but UTC still shows. What is the simplest way to replace 'UTC' with 'CST' or, alternatively, remove 'UTC' altogether since I don't need the designation in the field itself?
You can use a plain sql replace function inline
select replace(TIMESTAMP_SUB(TIMESTAMP (started_at), INTERVAL 5 HOUR), 'UTC','') AS CST
The above searches the result of your expression (provided in your question) for 'UTC' and replaces it with nothing ''. You could also replace it with 'CST' as you noted.
Obligatory warning: I believe your query will only be correct half the year as long as DST is observed? You might want to look into sys.time_zone_info and its reference on the MSDN.
My advise is to convert the timestamp to a datetime local value:
select datetime(started_at, 'America/Chicago') as started_at_cst
Note that the time zone is not stored in the data value. Instead, this encodes the value in the string.
If you want to include the time zone value, I have found that the best approach is to use a string (argghh!). The following constructs a string:
format_timestamp('%F %X%z', started_at, 'America/Chicago') as started_at_str
which can be converted easily into a timestamp for date/time calculations:
timestamp(started_at_str)

Extract date,month,year and month name from the unix timestamp with postgresql

I use postgres for the rails app and I have a unix timestamp in postgresql db. I have a requirement to select and group by the dd-mm-yyyy and by month name.
Consider I have the following unix timestamp
1425148200
and I would need to change this to datetime and I used to_timestamp which returned
2015-02-28 18:30:00 UTC
and I tried to convert the datetime to local timezone using
::timestamp without time zone AT TIME ZONE 'IST'
but that did not give time in required timezone and instead it returned
2015-02-28 16:30:00 UTC
and I tried to get the date part using ::date which returned
Sat, 28 Feb 2015
So please help me get the dd-mm-yyyy in specified timezone and month name(March) from the unix timestamp.
Thanks in Advance!
select to_char(to_timestamp('1425148200')::timestamptz at time zone 'UTC-5:30','DD-MM-YYYY & of course Month')
01-03-2015 & of course March
It is postgres mistake I guess
according to http://www.postgresql.org/docs/7.2/static/timezones.html