RFC3339 format in PostgreSQL - postgresql

I store a time as VARCHAR(30) as we can see it below:
I know it is far from best practices.. there is some way to convert such a string into PostgreSQL's time ?

Simply casting can do the trick like:
SELECT time::timestamptz FROM table;
Proof:
SELECT '2016-08-12T15:15:01.100001Z'::timestamptz;
timestamptz
-------------------------------
2016-08-12 15:15:01.100001+00
(1 row)

Related

Converting varchar to date in postgresql (date_parse doesn't work)

Running this existing query in presto:
date(date_parse(activation_date, '%%m-%%d-%%Y')) from table1
gives the error
"Invalid format: "02/06/2022""
Activation_date is varchar, showing MM/DD/YYYY
How do I convert it to a date so that I can join it to a column that is already in postgresql date type? Thank you so much!
The expected format is %m/%d/%Y in Trino (formerly PrestoSQL).
trino> SELECT date(date_parse('02/06/2022', '%m/%d/%Y'));
_col0
------------
2022-02-06
https://trino.io/docs/current/functions/datetime.html?highlight=date_parse#mysql-date-functions
date_parse is not a Postgres function.
You don't need to escape % in Postgres strings.
Your format has - while your string has /.
If your DateStyle is set to MDY (Month Day Year), simply cast the string to a date.
# SELECT current_setting('datestyle');
current_setting
-----------------
ISO, MDY
# select '02/06/2022'::date;
date
------------
2022-02-06
See Date/Time Input for more.

How to convert varchar to timestamp in postgreSQL?

I have data as following, But the column type is Varchar:
2019-09-28T23:59:59.52Z
I assume 52 here is milli seconds, If so..
I would like to convert it as following and change the column type to timestamp:
2019-09-28 23:59:59.52
Can someone let me know how I can convert in postgreSQL?
EDIT:
I can see data in table as (since the column type is varchar):
2019-09-28T23:59:59.52Z
Instead, I want data in the table to be shown as:
2019-09-28 23:59:59 ( and may be .52, if possible)
I need to change the column type to timestamp as well, I guess, Please help with that too.
Answer:
Tim has provided a solution, You can follow that.
But, In my case, It is prod env, So, I have just changed the type using:
ALTER TABLE my_table ALTER COLUMN my_column TYPE TIMESTAMP USING my_column::timestamp without time zone;
Thanks
Your timestamp string literal is already in a format which can be directly cast in Postgres:
SELECT '2019-09-28T23:59:59.52Z'::timestamp; -- 2019-09-28 23:59:59.52
As a test, let's add one day to make sure it's working:
SELECT '2019-09-28T23:59:59.52Z'::timestamp + interval '1 day';
-- 2019-09-29 23:59:59.52
If you want to actually add a new timestamp column using string data from another column, then try:
ALTER TABLE yourTable ADD COLUMN new_ts TIMESTAMP;
UPDATE yourTable SET new_ts = old_ts::timestamp;
ALTER TABLE yourTable DROP COLUMN old_ts;
ALTER TABLE yourTable RENAME COLUMN new_ts TO old_ts; -- optional
The last ALTER statement is optional if you want the new bona fide timestamp column to bear the same name as the old text timestamp column.

When do I need to cast a value as a date?

I'm working myself through the Datacamp SQL track, and I'm currently working with date values. I've encountered two examples which seem contradictory to me.
-- Count requests created on January 31, 2017
SELECT count(*)
FROM evanston311
WHERE date_created::date='2017-01-31';
And:
-- Count requests created on February 29, 2016
SELECT count(*)
FROM evanston311
WHERE date_created>= '2016-02-29'
AND date_created< '2016-03-01';
Why do I need to cast the value as date in the first case but not the other?
As with most typed languages, you can rely on implicit type casting... until you can't.
Something like date_created >= '2016-02-29' Postgres can use the type of date_created to figure out how to implicitly cast '2016-02-29'. There's no ambiguity. But sometimes Postgres can't make a guess at all.
OTOH a function like date_part has multiple signatures date_part(text, timestamp) and date_part(text, interval). If you pass it a date string...
test=# select date_part('day', '2019-01-03');
ERROR: function date_part(unknown, unknown) is not unique
LINE 1: select date_part('day', '2019-01-03');
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
...Postgres cannot make a guess because the second string could be interpreted as either a timestamp or an interval type. You need to resolve this ambiguity.
# select date_part('day', '2019-01-03'::date);
date_part
-----------
3
Now that Postgres knows you're passing in a date it can correctly guess to use it as a timestamp.
Another reason is as a cheap way to truncate timestamps. In your example date_created::date = '2017-01-31' will truncate date_created to be a date and make the comparison work. Of course, date_created should already be a date...
You can use it on the value being compared if you're not sure if that value will be a date or a timestamp.
select * from table
where date_created = $1::date
This will work the same with '2019-01-02' or '2019-01-02 03:04:05'.
Which brings us to our final reason: making up for bad schemas. Like if date_created is actually a timestamp, or all too common, text. In that case you need to explicitly control how comparisons are made. For example, let's say we had text_created of type text that contained timestamps as strings: naught. And maybe some poorly formatted data crept in that has extra spaces on the end...
-- Text comparison compares the values exactly.
test=# select * from test where text_created = '2019-01-04';
date_created | time_created | text_created
--------------+--------------+--------------
-- Date comparison compares as dates ignoring the extra whitespace.
test=# select * from test where text_created::date = '2019-01-04';
date_created | time_created | text_created
--------------+--------------+--------------
| | 2019-01-04
See Chapter 10. Type Conversion in the Postgres docs for more.

How to change default timestamp format in PostgreSQL [duplicate]

This question already has answers here:
in postgres, can you set the default formatting for a timestamp, by session or globally?
(3 answers)
Closed 5 years ago.
I am brand new to PostgreSQL coming from a few years in a company who solely using MySQL and I am a little caught off guard by the TIMESTAMP type:
CREATE TABLE example (
example_id SERIAL PRIMARY KEY,
time_utc TIMESTAMP
);
INSERT INTO example (time_utc) VALUES (NOW());
SELECT * FROM example;
example_id | time_utc
------------+----------------------------
1 | 2017-11-02 21:37:26.592814
I am aware that I can simply cast the field to its less precise form:
SELECT example_id, time_utc::timestamp(0)
and am also aware that I can declare the precision in the table definition:
time_utc TIMESTAMP(0)
But is there a way to change this to be the default precision for all TIMESTAMP fields? And similarly, is there a way to change the behavior of NOW() to match this format (including its lack of timezone)?
For example in MySQL:
SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2017-11-02 21:41:26 |
+---------------------+
PostgreSQL:
SELECT NOW();
now
-------------------------------
2017-11-02 21:42:48.855801+00
Honestly I just can't think of any time in the past I have wished for more precision out of MySQL's timestamps and the less precise form is objectively easier on the eyes. Is this an easy configuration change or is this just something I need to suck up and deal with in my transition to PostgreSQL?
Thanks
The date/time style can be selected by the user using the SET datestyle
command, the DateStyle parameter in the postgresql.conf
configuration file, or the PGDATESTYLE environment variable on the
server or client.
https://www.postgresql.org/docs/current/static/datatype-datetime.html#datatype-datetime-output
The available options (masks) are also listed at the same reference. But they may not provide for what you want exactly. Beyond that you have the to_char() function
The formatting function to_char (see Section 9.8) is also available as
a more flexible way to format date/time output.
https://www.postgresql.org/docs/current/static/functions-formatting.html

Modify timestamp

I have a timestamp like 2014-08-17T06:16:55.967Z that I want to insert in a Postgres db, but I want to remove just the milliseconds and keep the 'T' and the 'Z'. Anyone know how that is possible? I've tried 2014-08-17T06:16:55.967Z::timestamp(0) or timestamptz(0), but they both take away what I want to keep.
I would like 2014-08-17T06:16:55Z.
date_trunc
select date_trunc('second', '2014-08-17T06:16:55.967Z'::timestamp);
date_trunc
---------------------
2014-08-17 06:16:55
http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
The T and Z in the input string are not saved in the timestamp column. If you want to show them then format the output
select to_char(
date_trunc('second', '2014-08-17T06:16:55.967Z'::timestamp),
'YYYY-MM-DD"T"HH24:MI:SSZ'
);
to_char
----------------------
2014-08-17T06:16:55Z
http://www.postgresql.org/docs/current/static/functions-formatting.html