Trailing zeros omitted when inserting to postgres - postgresql

While inserting date with milliseconds part containing zero is skipping in PostgreSQL. If it have non-zero part in date, it will insert correctly into db.
eg: 2019-06-01 11:59:59:371Z this will insert correctly into db but when I am inserting '2010-06-21 11:59:59:010Z' then will become '2010-06-21 11:59:59:01Z' last zero part is skipped.
I used a query
SELECT to_char(date, 'YYYY-MM-DD HH:MI:SS:MSZ')
FROM table_name;
then I will get data correctly but it is in string format and if i changed to time.Time format then zero part is skipped.
Is any method to forcefully store milliseconds without skipping zero to postgres or any method to resolve this issue
2099-06-21T23:59:59.371Z -> 2099-06-21T23:59:59.371Z
2099-06-21T23:59:59.000Z -> 2099-06-21T23:59:59Z
2099-06-21T23:59:59.010Z -> 2099-06-21T23:59:59.01Z
2010-06-21T23:59:59.001Z -> 2010-06-21T23:59:59.001Z
2010-06-21T23:59:59.100Z -> 2010-06-21T23:59:59.1Z

Trailing zeros behind the decimal separator are irrelevant for the accuracy of a number.
If your application expects a certain fixed number of digits after the decimal separator, format the timestamp appropriately with the to_char function when you query the table.
If you want to avoid sprinkling your queries with to_char, define a view on the table that formats the timestamp as a string and use that view in your queries.
By all means, don't store timestamps as strings in a table. You would lose validity checks and date arithmetic, and you'd waste storage space.

Related

How to truncate date in postgres?

I am using below condition to truncate date in postgres
to_date(to_char(trunc(appointment_date),'YYYYMMDD')||appointment_end_time,''YYYYMMDDHH24:MI:SS')AS tq
How I can use this in postgres ?
Strange data typing, sometimes requires strange, looking at least, queries. Try (see fiddle)
date_trunc('day',appointment_date)
+ substr(appoinment_end,12)::interval
As your to_char() call uses the format 'HH24:MI:SS' for the "time" column, you can cast that column directly to a time value, e.g. using the :: operator: appointment_end_time::time.
To build a new timestamp from the date part of the appointment_date and the time value, just add them:
appointment_date::date + appointment_end_time::time
So first the timestamp is converted to a date (that does not have a time), and then the time value is added to that, which yields a timestamp.
Note that to_date() returns a date so your code would remove the just added time part again. You would need to use to_timestamp() if you really want a timestamp as the result.
To answer the question's title "how to truncate date in Postgres?" (which in reality refers to a timestamp not a date): you can either cast it to a date (see above) or you can use date_trunc() (not trunc()) with a unit to which it should be truncated. However, date_trunc returns a timestamp not a date value, so you couldn't add a time to the result.

Postgres Date Compare with ISO timestamp

When I perform a > than query on a timestampz field it seems to include dates that are equal to the date I'm querying with. At least when I'm comparing to an ISO date string?
select
created,
to_char(created, 'MI:SS:MS')
from
private.event
where
created > '2020-03-24T05:14:08.082Z'
Results
created |to_char |
-------------------|---------|
2020-03-24 18:14:08|14:08:082|
2020-03-24 18:14:08|14:08:180|
I'm not expecting the first row in that result.
FYI if I adjust the query so that I compare with '2020-03-24T05:14:08.083Z' it goes away.
Does anyone know whats going on here ?
Postgres timestamps have microsecond resolution even if they're displayed with millisecond resolution. So you're effectively searching for >'2020-03-24T05:14:08.082000Z' while that first result is probably non-zero in one or more of those last three hidden digits.

postgreSQL increment number in output

I am extracting three values (server, region, max(date)) from my postgresql> But I want to extract an additional 4th field which should be the numerical addition of 1 to 3rd field. I am unable to use date add function as in the database date field is defined as an integer.
date type in DB
date|integer|not null
tried using cast and date add function
MAX(s.date)::date + cast('1 day' as interval)
Error Received
ERROR: cannot cast type integer to date
Required output
select server, region, max(alarm_date), next date from table .....
testserver, europe, 20190901, 20190902
testserver2, europe, 20191001, 20191002
next date value should be the addition to alarm_date
To convert an integer like 20190901 to a date, use something like
to_date(CAST(s.date AS text), 'YYYYMMDD')
It is a bad idea to store dates as integers like that. Using the date data type will prevent corrupted data from entering the database, and it will make all operations natural.
First solution that came to my mind:
select (20190901::varchar)::date + 1
Which output 2019-09-02 as type date.
Other solutions can be found here.

Converting long (numbers) text datatype (with blank values) to date

I have troubles converting HubSpot UNIX timestamp to date. Timestamp is stored as text value.
Value looks like this:
1549324800000
My logic was first to convert the number to bigint and later converted it to date using:
TO_CHAR(TO_TIMESTAMP(properties__vape_station__value)), 'DD/MM/YYYY')
What would be the best way to achieve converting UNIX Timestamp in text type to date in PostgreSQL 11.
You can cast the value in that column to a bigint and then use to_timestamp.
But apparently that column also stores empty strings rather than NULL values if no value is present, so you need to take that into account:
to_timestamp(nullif(trim(properties__vape_station__value),'')::bigint/1000)
This would still fail however if anything else than a number is stored in that column.

Converting string timestamp into date

I have dates in a postgres database. The problem is they are stored in a string field and have values similar to: "1187222400000" (which would correspond to 07.08.2007).
I would like to convert them into readable dates usind some SQL to_date() expression or something similar but can't come up with the correct syntax to make it work.
There really isn't enough information here for a conclusion, so I propose this 'scientific-wild-ass-guess' to resolve your puzzle. :)
It appears this number is UNIX 'epoch time' in milliseconds. I'll show this example as if your string field had the arbitrary name, 'epoch_milli'. In postgresql you can convert it to a time stamp using this statement:
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + epoch_milli * INTERVAL '1 millisecond';
or using this built-in postgresql function:
SELECT to_timestamp(epoch_milli / 1000)
either of which, for the example '1187222400000', produces the result
"2007-08-15 17:00:00-07"
You can do some of your own sleuthing with quite a few values selected similarly to this:
SELECT to_timestamp(epoch_milli/1000)::DATE
FROM (VALUES (1187222400000),(1194122400000)) AS val(epoch_milli);
"Well, bollocks, man. I just want the date." Point taken.
Simply cast the timestamp to a date to discard the excess bits:
SELECT to_timestamp(epoch_milli / 1000)::DATE
Of course its possible that this value is a conversion or is relative to some other value, hence the request for a second example data point.