last_day in PostgreSQL - postgresql

The oracle last_day function return the last day of the month.
example:
nls_date_format='YYYY-MM-DD H24:MI:SS'
select last_day(sysdate) from dual;
LAST_DAY(SYSDATE)
-------------------
2014-06-30 15:45:43
oracle return the time value as well.
I have tried below sql in PostgreSQL which return the last day of month but time value is "00:00:00".
select (date_trunc('month', now()) + interval '1 month -1 day')::timestamp(0);
?column?
---------------------------
2014-06-30 00:00:00
(1 row)
the sql return the date correctly but I want date and time like oracle.

select (
date_trunc('month', now())
+ interval '1 month -1 day'
+ now()::time
)::timestamp(0);

The function last_day() should do the trick. This function should be found in a extenstion package called "orafce". Containing other functions used in Oracle.
Install the correct version of orafce package (if needed):
apt-get install postgresql-9.1-orafce
SQL:
Create Extension orafce
If error rename orafce--3.0.sql to orafce--3.03.sql or user later version of orafce.
Use the function:
SELECT last_day('2015-01-01')
Works like expected and the result is '2015-01-31'

Related

Finding the last date of the previous quarter from current date in PostgreSQL

For example: If my current date is 2022-07-21, my query should give me 2022-06-30.
I could easily do it in IBM DB2 but struggling in postgresql.
You can truncate the current date to its quarter, then remove 1 day from that (and potentially cast back to date):
-- You really only need the last column, the other two just show the different steps in the process
SELECT DATE_TRUNC('quarter', CURRENT_DATE)
, DATE_TRUNC('quarter', CURRENT_DATE) - '1 day'::INTERVAL
, (DATE_TRUNC('quarter', CURRENT_DATE) - '1 day'::INTERVAL)::DATE
outputs
+---------------------------------+---------------------------------+----------+
|date_trunc |?column? |date |
+---------------------------------+---------------------------------+----------+
|2022-07-01 00:00:00.000000 +00:00|2022-06-30 00:00:00.000000 +00:00|2022-06-30|
+---------------------------------+---------------------------------+----------+

Oracle And Postgres results different [duplicate]

In case of Oracle
the Query
select SYSDATE - TO_DATE('23-03-1022','dd-mm-yyyy') from dual;
is Giving the Output
SYSDATE-TO_DATE('23-03-1022','DD-MM-YYYY')
------------------------------------------
21715.2233
In case of EDB/Postgres it is-
select SYSDATE - TO_DATE('23-03-1022','dd-mm-yyyy') as date;
date
---------------------
21715 days 05:23:13
(1 row)
How can i get the Same output as oracle in case Of Postgres ?
What does .2233 tells in case of Oracle?
In Oracle, SYSDATE is a function that returns both date and time component. Difference of two DATE datatype values returns number of days between them. Therefore, as SYSDATE also contains hours, minutes and seconds, you'll almost always get a decimal number as the result (unless you run that piece of code at midnight).
Therefore, I presume that you'd - actually - want to truncate SYSDATE which then "removes" time component (sets it to 00:00:00):
SQL> select SYSDATE - TO_DATE('30-12-1899','dd-mm-yyyy') from dual;
SYSDATE-TO_DATE('30-12-1899','DD-MM-YYYY')
------------------------------------------
44715.3208
SQL> select trunc(SYSDATE) - TO_DATE('30-12-1899','dd-mm-yyyy') from dual;
TRUNC(SYSDATE)-TO_DATE('30-12-1899','DD-MM-YYYY')
-------------------------------------------------
44715
SQL>
As of 0.2279: it is - as I said - number of days. To quickly demonstrate it: if you want to get number of hours, you'd multiply it by 24 (the rest by 60 to get minutes, and its rest by 60 again to get seconds):
SQL> select 0.2279 * 24 as hours from dual;
HOURS
----------`enter code here`
5.4696
SQL> select 0.4696 * 60 as minutes from dual;
MINUTES
----------
28.176
SQL> select 0.176 * 60 as seconds from dual;
SECONDS
----------
10.56
SQL>
Which means that you ran that query today at 05:28:10.

Date Subtraction in Postgres and include both the dates

I am trying to get the difference between two dates using this
'2021-07-02'::date - '2020-07-03'::date
The actual difference if you include the end date as well is 365 days but the result from this query is 364 days. Has anyone worked with something similar?
I did think about adding 1 to the result but just wanted to check if there is a more elegant way to do this.
That is documented behavior per Date/time operators.
The reason being that the date subtraction is from Midnight to Midnight so you don't get the first day included. As demo:
--The date is effectively set to Midnight
select '2020-07-03'::date::timestamp;
timestamp
---------------------
2020-07-03 00:00:00
--Which means this
select '2021-07-02'::date - '2020-07-03'::date;
?column?
----------
364
--Is the same as
select '2021-07-02 00:00:00'::timestamp - '2020-07-03 00:00:00'::timestamp;
?column?
----------
364 days
If you want to include the start date then you need to go to the previous days Midnight:
select '2020-07-03 00:00:00'::timestamp - '1 day'::interval;
?column?
---------------------
2020-07-02 00:00:00
select '2021-07-02 00:00:00'::timestamp - ('2020-07-03 00:00:00'::timestamp - '1 day'::interval);
?column?
----------
365 days
--Getting back to date.
select '2021-07-02'::date - ('2020-07-03 00:00:00'::date - '1 day'::interval)::date;
?column?
----------
365
Or an alternate solution:
select
count(*)
from
generate_series('2020-07-03'::timestamp, '2021-07-02'::timestamp, '1 day');
365
This generates a set of dates at one day intervals over the time period and the count(*) adds them up.

Timestamp with timezone in PostgreSQL 9.6

I am currently searching my transaction table using the following query. The second TO_TIMESTAMP is specified as 2019-08-21..
SELECT t.* FROM Transaction t WHERE t.datetime >= TO_TIMESTAMP('2019-01-01T07:54:34','YYYY-MM-ddTHH:MI:SS')
AND t.datetime < TO_TIMESTAMP('2019-08-21T14:38:34','YYYY-MM-ddTHH:MI:SS') AND (t.location_1 = 2001 OR t.location_2 = 2001);
It returns me the following result:
When i change the second TO_TIMESTAMP to 2019-08-22.. It returns me the current day's result. I am not sure why I need to add one more day in order to retrieve the current day's result..
The current timezone in the PostgreSQL 9.6 is:
This is your problem:
SELECT TO_TIMESTAMP('2019-08-21T14:38:34','YYYY-MM-ddTHH:MI:SS');
to_timestamp
------------------------
2019-08-21 00:38:34+00
(1 row)
The unescaped T confuses the parser (the actual result may even be buggy).
Use the correct format string:
SELECT TO_TIMESTAMP('2019-08-21T14:38:34','YYYY-MM-DD"T"HH24:MI:SS');
to_timestamp
------------------------
2019-08-21 14:38:34+00
(1 row)

Calculating a date in Postgres by adding months?

I have a postgres table that has the following fields
start_date,duration
duration contains any number of months, so to calculate the end date you add the months in duration to the start date. Now I want to do something like this with a postgres query.
SELECT *
FROM table
WHERE start_date > '2010-05-12'
AND (start_date + duration) < '2010-05-12'
Is this possible and how does one right the syntax?
The version of my postgres is PostgreSQL 8.1.22 on x86_64-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)
try:
(start_date + (duration * '1 month'::INTERVAL)) < '2010-05-12'
or
(start_date + (duration || ' month')::INTERVAL) < '2010-05-12'
More info: Date/Time Functions and Operators
You might find this article useful: PostgreSQL: month := interval '30 days';
Also this link: http://wiki.postgresql.org/wiki/Working_with_Dates_and_Times_in_PostgreSQL, more specifically the section called "WORKING with DATETIME, DATE, and INTERVAL VALUES".