Unexpected result from Redshift TIMEZONE function (convert timestamp column from UTC to another timezone) - sql

Based on my understanding of the documentation, I am expecting the TIMEZONE function to convert any timestamp from UTC (by default) to 'timezone'.
I know for a fact that the timestamp columns of the server I'm pulling data from are set to UTC. Therefore, if I convert the timestamp column to EST, I should see a five hour difference between UTC and EST (according to worldtimebuddy).
However, when I run the following query
select
time_column
, timezone('est', time_column) as to_est
from
my_table
order by
time_column desc
limit 1
I get
sent_at
to_est
2022-11-15 17:50:26.280
2022-11-15 22:50:26.280
If I'm interpreting this correctly, the result is telling me that UTC is five hours behind EST, when really, UTC is five hours ahead of EST (right?).
In other words, I was expecting
sent_at
to_est
2022-11-15 17:50:26.280
2022-11-15 12:50:26.280
Why am I seeing a -5 hour difference from UTC to EST instead of +5?

instead of timezone use
convert_timezone('EST', time_column)
That is the way redshift shows in the manual
the syntax is
CONVERT_TIMEZONE ( ['source_timezone',] 'target_timezone', 'timestamp')
but the source time zone is by default UTC, so you don't need to add it to your code

Related

PostgreSQL get results in current time zone

as said in the title I would like to have a query that returns the value of the time stamp in my current time zone (even according summer time!).
my_table is:
|timestamp|name|value|property1|property2|
|---|---|---|---|---|
|2021-08-01 00:00:00+00|10|0.44|0|0|
|2021-08-01 00:05:00+00|15|0.76|0|0|
|2021-08-01 00:10:00+00|12|0.28|0|0|
(Don't ask me why I cannot put this table directly in markdown...prob cause the dates)
Now for example if I have to select the 24h corresponding to the entire day in my time zone at the moment my solution is:
SELECT timestamp AT TIME ZONE 'CEST',name,value
FROM my_table
WHERE name IN (10,11,12)
AND timestamp BETWEEN '2021-08-01 00:00:00+02' AND '2021-08-02 00:00:00+02'
ORDER BY timestamp DESC
As you can see there is a problems here:
I have to specify every time if I is CEST or CET (now is CEST here)
and then I have to add +02 at the end of the dates (or +01 in CET)
There is a way to avoid this conceptual repetition?? any suggestion even to improve the query is appreciated
the command SELECT version(); gives me back PostgreSQL 12.7
Set your session's timezone appropriately.
set timezone TO 'Europe/Berlin';
select '2021-08-01 00:00:00+00'::timestamptz;
timestamptz
------------------------
2021-08-01 02:00:00+02
select '2021-12-01 00:00:00+00'::timestamptz;
timestamptz
------------------------
2021-12-01 01:00:00+01
select '2021-08-01 00:00:00'::timestamptz;
timestamptz
------------------------
2021-08-01 00:00:00+02
What is your session timezone set to now?

Extract date part from timestamptz

I am trying to extract the hour from a timestamp with a timezone. However, my times are coming up incorrectly.
Here's an example, I am using Dbeaver with my timezone set to EST:
SELECT '2020-01-24 14:27:12' AT TIME ZONE 'US/Pacific' as foo,
EXTRACT(HOUR FROM foo) as ex,
DATE_PART('HOUR', foo::timestamp) as dp
RETURNS:
foo |ex |dp
2020-01-24 17:27:12 |22 | 22
Why is my time coming up 3 hours ahead, it should be 3 hours behind?
Extract and DATE_PART don't seem to get me the hour I would like. It looks like it's taking 17 as EST and then converting it to UTC. Here's what I am expecting to get:
foo |ex |dp
2020-01-24 11:27:12 |11 | 11
Check if your timezone is set to EST:
SELECT current_setting('TIMEZONE');
or with:
show timezone;
If it is not you can set it like this:
set timezone to est;
AS shown in this DEMO
If that is not working try with convert_timezone
select convert_timezone('US/Pacific', '2020-01-24 14:27:12')
And exploring the mater on hand I have found this fact:
Note Amazon Redshift doesn't validate POSIX-style time zone
specifications, so it is possible to set the time zone to an invalid
value. For example, the following command doesn't return an error,
even though it sets the time zone to an invalid value.
set timezone to ‘xxx36’;
from this source: https://docs.aws.amazon.com/redshift/latest/dg/CONVERT_TIMEZONE.html
'AT TIME ZONE' does not work like you are expecting. Use convert_timezone() instead.
SELECT
'2020-01-24 14:27:12' AT TIME ZONE 'US/Pacific' as foo,
-- expected '2020-01-24 6:27:12' got '2020-01-24 22:27:12+00'
convert_timezone('UTC', 'US/Pacific', CAST('2020-01-24 14:27:12' AS TIMESTAMP WITHOUT TIME ZONE)) as bar
-- expected '2020-01-24 6:27:12' got '2020-01-24 06:27:12'
;
'AT TIME ZONE' interprets the timestamp as being relative to the specified time zone and converts it to a TIMESTAMPTZ offset to UTC. That is in the above example it converts from US/Pacific to UTC, not the other way around.
It works perfectly fine for me (using dbVisualizer).
The issue is with your SQL Client.
SQL clients often impose formatting that impacts the values you see. You can test this by converting values to Text before sending them to your SQL client:
SELECT
'2020-01-24 14:27:12' AT TIME ZONE 'US/Pacific' as foo,
foo::text as t,
EXTRACT(HOUR FROM foo) as ex,
DATE_PART('HOUR', foo::timestamp) as dp
For me, this results in:
2020-01-24 22:27:12+00 2020-01-24 22:27:12+00 22.0 22.0
Try it in your SQL client and see what happens.

Automatically convert dates based on time zone

Objective:
Knowing that my main column dates is in UTC time but is taking data from the Time zone 'Dateline Standard Time', how can I ensure that my query accounts for the offset without having to manually do DATEADD(HOUR,-8,column_name). This is especially important for day light savings periods.
select
, created_at
, created_at at time zone 'Dateline Standard Time' as dates_zone
The output of this is:
created_at created_at_timezone
2019-07-01 00:45:04.000 2019-07-01 00:45:04.000 -12:00
but I'd rather have the end result as such:
(which is basically UTC-8)
created_at_modified
2019-06-30 16:45:04.000
You can convert the date to datetimeoffset:
SELECT CONVERT(datetimeoffset,created_at) AT TIME ZONE 'Dateline Standard Time' created_at_modified
FROM …
;

Group by time with timezone conversion in Postgresql

I am working with time data that is currently stores in UTC but I want it to be in PST, which is 8 hours behind. I have a pretty lengthy and involved query, but the only thing I am interested in is the time right now so I have included those parts. I want to convert the times to PST and then group by the date for the last week of data. The query has the following structure:
select
date_trunc('day', time1) AT TIME ZONE 'US/Pacific'
...
where
time1 AT TIME ZONE 'US/Pacific' > now() AT TIME ZONE current_setting('TimeZone') - INTERVAL '168 HOURS'
...
group by date_trunc('day', time1)
This results in the following time groupings. From my understanding, it groups from the 0:00 UTC, which is 16:00 in PST. However, I want the groupby to start at 0:00 PST. How do I do this? Right now, the counts in each group are misleading for each day because they go from 4 pm to 4 pm instead of 12 am to 12 am. For example, Sundays have uncharacteristically high counts because Sunday includes part of Monday's data in the groupby. I would appreciate any input to fix this issue. Thank you.
The answer depends on whether it is a timestamp with time zone or one without:
If it's a timestamp with time zone, you can convert to PST with select time1 AT TIME ZONE 'US/Pacific' and get the date with select date_trunc('day', time1 AT TIME ZONE 'US/Pacific')
If it's a timestamp without time zone stored in UTC that you want to convert, you first have to tell PostgreSQL to interpret it as UTC, then convert it, like so: select (time1 AT TIME ZONE 'Z') AT TIME ZONE 'US/Pacific' and of course you can get the date with select date_trunc('day', (time1 AT TIME ZONE 'Z') AT TIME ZONE 'US/Pacific')
In either case you have to convert time zones before truncating to the day level or you may end up with inaccurate results.

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