How to convert column data from GMT timezone to localtime in postgres? - postgresql

I have a column "last_status_change_date" which has data in GMT timestamp. I need to convert this data in "GMT-6" ..How can i achieve this ?
select last_status_change_date from bss_calling_card where card_sn ='030400091074';
last_status_change_date
-------------------------
2020-01-03 17:06:51
(1 row)
Result set should be like:
last_status_change_date
-------------------------
2020-01-03 11:06:51
(1 row)

The fallacy of timestamp with out timezone. Try:
select (cast(last_status_change_date as timestamp with time zone) at time zone 'UTC') at time zone '-06:00' last_status_change_date from ...;
This takes your timestamp and converts type to timestamp with time zone then informs Postgres which time zone it's currently in and finally indicates the time zone for your desired result.

Related

Postgres cast to TIMESTAMPTZ

What is the behavior of PostgreSQL when we cast a DATE to TIMESTAMP to TIMESTAMPTZ
What time zone is used?
PostgreSQL server
Client that run the query (Current session)
If you cast a date to a timestamp, time zones don't play a role, because both data types are without a time zone. The resulting timestamp will be the beginning of the day.
If you cast date to timestamp with time zone, resulting timestamp will be the beginning of the date in the time zone defined by the parameter timezone in your current session.
SHOW timezone;
TimeZone
---------------
Europe/Vienna
(1 row)
SELECT CAST (DATE '2021-01-15' AS timestamp);
timestamp
---------------------
2021-01-15 00:00:00
(1 row)
SELECT CAST (DATE '2021-01-15' AS timestamp with time zone);
timestamptz
------------------------
2021-01-15 00:00:00+01
(1 row)
Casting date to timestamp will append time 00:00:00.0 to the date.
The time zone of the current server session will be used.
By default this is the time zone setting of Postgresql server.
You can change the time zone of the current server session like this:
set time zone 'Europe/Sofia';
I do not think that the time zone of the client has any effect. More on this issue here.
Edit
As Adrian Klaver noticed "When dealing with timestamps it's best to assume the worst". Therefore better set the session time zone explicitly.
Given the situation where one needs to change the column type from integer (as epoc seconds) to timzezonetz ->
casting directly from integer to timezonetz is not possible.
but you can do this:
ALTER TABLE table_name ALTER COLUMN column_name TYPE timestamptz
USING column_name::abstime::timestamptz

How to treat string as UTC timestamp?

I have to read strings like '20190608070000' as timestamps given in UTC. Is there an easy way to do that?
This one takes UTC but needs formatted input:
postgres=# show time zone;
TimeZone
----------
CET
(1 Zeile)
postgres=# select timestamp without time zone '2019-06-08 07:00:00' at time zone 'UTC';
timezone
------------------------
2019-06-08 09:00:00+02
(1 Zeile)
Whereas to_timestamp() invariably treats all input as local time as far as I see, so the output is shifted the wrong way:
postgres=# SELECT to_timestamp('20190608070000', 'YYYYMMDDHH24MISS') AT time zone 'UTC';
timezone
---------------------
2019-06-08 05:00:00
(1 Zeile)
Actually I'm using PostgreSQL 9.6.
The return type of TO_TIMESTAMP is timestamp with time zone. The time shown is in your current session's time zone(with the UTC offset).
SET SESSION timezone TO 'CET';
SET
knayak=# SELECT to_timestamp('20190608070000', 'YYYYMMDDHH24MISS');
to_timestamp
------------------------
2019-06-08 07:00:00+02
When you transform it with AT TIME ZONE, it will show the time in UTC when it's 07:00 hours in your current time zone.
SELECT to_timestamp('20190608070000', 'YYYYMMDDHH24MISS') AT time zone 'UTC';
timezone
---------------------
2019-06-08 05:00:00
(1 row)
So, If you wish to read your timestamp in a desired format and treat that as UTC, cast the output of to_timestamp explicitly to timestamp (without time zone) and then apply AT TIME ZONE.
SELECT to_timestamp('20190608070000', 'YYYYMMDDHH24MISS') :: timestamp
AT time zone 'UTC';
timezone
------------------------
2019-06-08 09:00:00+02
(1 row)

Convert a UTC timezone in postgresql to EST (local time)

I am new to PostgreSQL and I was wondering if there is a direct way to just convert the timestamp values in a table to a different timezone using a function. In my case it is UTC to EST.
These are the values for example that I need to convert to EST (not just one value but all the values in the table)
date
-------------------
2015-10-24 16:38:46
2016-01-19 18:27:00
2016-01-24 16:14:34
2016-02-09 23:05:49
2016-02-11 20:46:26
Here in London, we are currently 1 hour ahead of UTC. So - if I take your timezone without timestamp and say it is in UTC I will get it printed for my local timezone.
richardh=> SELECT ((timestamp '2015-10-24 16:38:46') AT TIME ZONE 'UTC');
timezone
------------------------
2015-10-24 17:38:46+01
(1 row)
But you want "EST" which seems to be somewhere in the Americas, judging by the value returned. You can wrap the expression in a little SQL function if you wanted to.
richardh=> SELECT ((timestamp '2015-10-24 16:38:46') AT TIME ZONE 'UTC') AT TIME ZONE 'EST';
timezone
---------------------
2015-10-24 11:38:46
(1 row)
Edit: how to do it in a query
SELECT ((stored_timestamp AT TIME ZONE 'UTC') AT TIME ZONE 'EST') AS local_timestamp
FROM my_table;
Similarly
execute
SELECT '2015-10-24 16:38:46'::timestamp AT time zone 'EST';
timezone
------------------------
2015-10-24 21:38:46+00
(1 row)
I usually leave everything in UTC and convert when it is time to show.
I use something like:
SELECT my_date_utc AT time zone 'utc' at time zone 'est' From ....
If you have problem accessing with your zone, you can simply pass your zone interval also.
To convert timestamp from IST to UTC.
SELECT '2020-12-14 06:38:46'::timestamp AT time zone INTERVAL '+05:30';
timezone
------------------------
2015-10-24 11:38:46+00
(1 row)
To convert timestamp from UTC to IST.
SELECT '2020-12-14 06:38:46'::timestamp AT time zone INTERVAL '-05:30';
timezone
------------------------
2020-12-14 12:08:46+00
(1 row)
It is 12:22 here in Los Angeles now.
I find that I have to reverse the UST and america/los_angeles arguments:
ods=> SELECT NOW(),(NOW() AT TIME ZONE 'america/los_angeles') AT TIME ZONE 'utc';;
now | timezone
-------------------------------+-------------------------------
2022-04-22 19:22:35.943605+00 | 2022-04-22 12:22:35.943605+00
(1 row)
Am I missing something?
You should always store the main reference of a date in UTC and either convert it to a time zone in your queries or store the specific timezone version of the data in another column. The reason for this is that it is quick and easy to convert a date from UTC to another time zone as long as you know that the timezone that it is stored as is UTC. It takes the guess work out of it. Alternatively, you can store the date WITH the timezone.
If you have an operation that automatically populates the date with the system clock of your server, then you can either
A: Change the operation to use UTC time
B: Change the system clock on the server to UTC
I had the same problem, I am working with different regions and timezones, I need to just fix the timezone in the query the way it doesn't effect other customers around the regions and I havent changed the table structure or any thing(Open–closed principle) . What I did In my query:
SELECT TO_CHAR(current_timestamp at time zone 'Australia/Melbourne', 'DD/MM/YYYY hh24:mi AM') as date_of_extract
This worked for me and I could change the 'UTC' defult timezone for my postgressql to the 'Australia/Melbourne'(any time zone you are looking into). hope this is helpful.
Building off of #Leandro Castro's answer...
To get current time in in timezone, use the CURRENT_TIME function:
SELECT CURRENT_TIME(0) AT time zone 'utc' at time zone 'est';

Retrieving UTC timestamptzs from postgres in the correct time zone

I store timestamps with time zone in my postgres database. The server time zone is UTC. All the timestamptzs are stored as UTC datetimes.
Now, I'd like to retrieve those timestamps, but for a specific time zone (e.g. US/Pacific). Because of daylight savings time, the correct time zone is sometimes PDT and sometimes PST. So I can't just run a query like select t at time zone 'pdt' because this will be wrong for the pst dates.
Is there a way to pull the dates from the database in the correct time zone?
According to the documentation, together with TIME ZONE code you can also specify locales. For your case you can use something like that:
ds=# SELECT current_setting('TIMEZONE');
current_setting
-----------------
UTC
(1 row)
ds=# SELECT now();
now
-------------------------------
2015-11-05 00:35:03.126317+00
(1 row)
pm7=# SELECT now() AT TIME ZONE 'America/Los_Angeles';
timezone
----------------------------
2015-11-04 16:35:06.344367
(1 row)

Date and time as UTC timestamp in Postgres

I have date and time fields in my table. Both are set in local server time.
Is it possible to cast both fields as a single UTC ISO timestamp?
Just add the two:
SELECT date_col + time_col AS timestamp_col
The type timestamp [without time zone] is stored as UTC timestamp internally anyway. Only the display is adjusted to the time zone setting of your session. If you need to display the timestamp as UTC timestamp, use the AT TIME ZONE construct:
SELECT timestamp_col AT TIME ZONE 'UTC';
Note that this returns a timestamp with time zone when applied to a timestamp.
Ample details:
Ignoring timezones altogether in Rails and PostgreSQL
For example, to display the timestamp as timestamptz in Moscow:
SELECT (date_col + time_col) AT TIME ZONE 'Europe/Moscow' AS tstz_col