Need help to identify the actual date time format - postgresql

I have been struggling since few days to identify correct format for sample input date:
2020-01-30 14:39:25.022000 +00:00:00
Background :
I am working on data migration with postgres. And, have identified that in DB, the datetime related fields like 'modifiedAt' have datatype as varchar, which is bit weird. These records have values in above mentioned format.
I have fixed it in new postgres DB instance with datatype as timestamp. After migrating data, these fields are showing datetime in following format:
2020-01-30 14:39:25
How can I format above date to give output in this dateformat 2020-01-30 14:39:25.022000 +00:00:00?
Any help will be appreciated.

First you want to use timestamptz not timestamp. timestamptz does not actually store the time zone, it just makes the value time zone aware. For more information on this see:
Time Stamps 8.5.1.3. Time Stamps.
Second it looks like you did something like timestamp(0) which reduced the precision to whole seconds. If you leave the precision alone you get:
select '2020-01-30 14:39:25.022000 +00:00:00'::timestamptz;
timestamptz
-----------------------------
01/30/2020 06:39:25.022 PST
-- I am in PST so the value gets rotated to that time zone for display.
-- If you want something closer to you desired output, then:
select to_char('2020-01-30 14:39:25.022000 +00:00:00'::timestamptz AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS.USOF');
to_char
-------------------------------
2020-01-30 14:39:25.022000+00

While your timestamp strings do appear to have a time zone component, it is +00, which is the default for timestamps. So, you might be able to just use TO_TIMESTAMP here with an appropriate format mask covering microseconds:
WITH yourTable AS (
SELECT '2020-01-30 14:39:25.022123 +00:00:00'::text AS ts
)
SELECT TO_TIMESTAMP(LEFT(ts, 26), 'YYYY-MM-DD HH24:MI:SS.US')
FROM yourTable;
Demo
The output value from the demo above is 2020-01-30 14:39:25.022123+00

Related

I have varchar column with "2022-11-30T17:30:00.000Z" format how can i transform it to timestamp with time zone column in postgres?

We are storing date time in "2022-11-30T17:30:00.000Z" format in var char column i know its totally wrong but I want to rectify the mistake and use the column as timestamp with time zone.
I Tried using column::timestamp AT TIME ZONE 'Asia/Calcutta' but still date and time is wrong as it does not considers +5:30 in my time zone.please suggest how can i transform the column or if i could use the same column.
select dtm from dashboard where (select dtm::timestamp AT TIME ZONE 'Asia/Calcutta')::date between '2022-11-30' and '2022-11-30' order by dtm;

date_trunc at time zone with original timestamptz

I have a single timestamptz that I want to date_trunc so it removes the hours:
2019-01-01T17:43-03 => 2019-01-01T00:00-03.
However, because date_trunc removes the timezone, I need to do it like this:
date_trunc('day', '2019-01-01T17:43-03'::timestamptz) at time zone '-03'
However, I do not want to hardcode the time zone, since the query is run with timestamptz in many different timezones (these are input to the query and not stored). So I want the timezone to be extracted from the original timestamp. I tried to do something like this, but it does not work:
date_trunc('day', '2019-01-01T17:43-03'::timestamptz) at time zone EXTRACT(...)
Related, I am trying to extract the timezone from a timestamptz, but just getting 0.
SELECT EXTRACT(timezone FROM TIMESTAMP WITH TIME ZONE '2019-01-01T00:00+03')
0
Can anybody help me with this?
I believe you may have a misconception about how timestamps and timezones are stored in PostgreSQL (because you seem to expect the -03 to be preserved when calling date_trunc and that you "want the timezone to be extracted from the original timestamp"). According to the documentation:
When a timestamp with time zone value is output, it is always converted from UTC to the current timezone zone, and displayed as local time in that zone. To see the time in another time zone, either change timezone or use the AT TIME ZONE construct (see Section 9.9.3).
Therefore, the statement that "different clients [that] have timestampts in many different timezones," while true, are all translated to UTC for storage, and then displayed in your local timezone (or the timezone you specify) for output. As such, calling date_trunc() will essentially truncate the UTC timestamp, and if you want it displayed in a specific timezone, you will need to add the AT TIME ZONE clause.
UPDATE: An example is here:
edb=# select date_trunc('day', '2019-01-01T17:43-03'::timestamptz) ;
date_trunc
------------------------
2019-01-01 00:00:00+00
(1 row)
edb=# set timezone to 'US/Pacific';
SET
edb=# select date_trunc('day', '2019-01-01T17:43-03'::timestamptz) ;
date_trunc
------------------------
2019-01-01 00:00:00-08
(1 row)
As you can see, date_trunc will append the timezone that I define—it is not omitted.

PostgreSQL how to convert date with timezone offset to UTC?

I have a PostgreSQL table with date field in the following format
2017-09-07T17:24:33+08:00
and I want to convert it to UTC time.
I've looked around but found no way to do that with this specific time format. What am I missing?
Thanks
timezone definition (https://www.postgresql.org/docs/9.1/functions-datetime.html) : The function timezone(zone, timestamp) is equivalent to the SQL-conforming construct timestamp AT TIME ZONE zone
SELECT timezone('UTC','2017-09-07T17:24:33+08:00');
if selecting from column,
with t as (
SELECT '2017-09-07T17:24:33+08:00' as tm
)
SELECT timezone('UTC',tm::timestamptz) as ts
from t;
I have a PostgreSQL table with date field in the following format: 2017-09-07T17:24:33+08:00
This is incorrect. Per Postgres documentation,
All timezone-aware dates and times are stored internally in UTC. They are converted to local time in the zone specified by the TimeZone configuration parameter before being displayed to the client.
To display a TIMESTAMP WITH TIME ZONE attribute (which, again, is stored internally in UTC) in a specific time zone, you have a few options:
By default, “They are converted to local time in the zone specified by the TimeZone configuration parameter before being displayed to the client.” This can be set in postgresql.conf, using the SQL command SET TIME ZONE, or using a number of other options.
Use the AT TIME ZONE construct.
So, in regards to your original question: You don't have to do anything to your timestamptz for Postgres to store it in UTC. To display your attribute in UTC, you can either change the TimeZone configuration paramter, or use the construct below:
SELECT dt_with_timezone AT TIME ZONE 'UTC' FROM my_table

Summer and wintertime postgres timezone/timestamp

I uploaded csv data into table in postgres. One of the columns is a character varying column with an epoch filling. The data going in is as following:
Example record: 1507656308.
The epoch character varying column is transformed to a timestamp column as follows:
select
TIMESTAMP WITH TIME ZONE 'epoch' + timestamp::integer * INTERVAL '1 second' as timestamp
from
table
The result appeared good and I continued with it. I live in the Netherlands and here we have the winter-summertime change twice a year. Apparently my data does not differentiate.
I tried to figure out my current timezone. Which I did like this:
SELECT EXTRACT(TIMEZONE FROM timestamp) FROM table;
Resulting in:
3,600.0000
When I try to figure out my general time zone I get this:
show timezone
= Europe/Berlin
How do I get my timestamps to recognize the summer vs wintertime? Or what did I do wrong?
Of all the creative ways to convert an epoch value (why is it stored as string?) to a timestamp with time zone, this is one of the more interesting one.
The simple and boring way is
SET timezone = 'Europe/Berlin';
SELECT to_timestamp(1507656308);
to_timestamp
------------------------
2017-10-10 19:25:08+02
(1 row)
The time zone offset for that is two hours, because on October 10, daylight savings time was in effect (Central European Summer Time).
Indeed:
SELECT extract(timezone FROM to_timestamp(1507656308));
date_part
-----------
7200
(1 row)
So everything is working as expected, right?

timezone aware date_trunc function

The following query
SELECT the_date FROM date_trunc('day', timestamp with time zone
'2001-01-1 00:00:00+0100') as the_date
results to
the_date
2000-12-31 00:00
Is there a way to tell date_trunc to do day/month/year conversions based on the timezone it is feeded with?
The expected output would be: 2001-01-1 00:00+0100
You need to specify at which time zone you want it to show
select
date_trunc(
'day',
timestamp with time zone '2001-01-1 00:00:00+0100' at time zone '-02'
) as the_date;
the_date
---------------------
2001-01-01 00:00:00
AT TIME ZONE
While the marked answer might be correct for the OP's weird circumstances it is more likely incorrect for others. You need to convert the timestamp returned by date_trunc to the proper timezone.
select
date_trunc(
'day',
some_timestamp at time zone users_timezone
) at time zone users_timezone as the_date;
The important thing to understand is date_trunc returns a timestamp with no timezone attached to it. You need to convert the timestamp to the proper timezone because the database client or whatever downstream might have a different timezone.
#Adam's answer is definitely more helpful. Although I think we can improve on it again because if we're truncating a Timestamp to a single day (or week/month/etc), then we want to make sure that we're dealing with a Date object, not a Timestamp. Otherwise we may give other pieces of code the impression that something just actually happened to occur at midnight (or potentially some other misleading time of day).
So I would use:
SELECT date_trunc('day', some_timestamp AT TIME ZONE users_timezone)::date AS the_date;
which casts the result to a Date, rather than Timestamp.
The result will be something like:
the_date
------------
2019-09-14
instead of the more misleading result of:
the_date
---------------------
2019-09-14 00:00:00