Odd result using Oracle trunc()? - oracle

Why
select trunc(to_date('23/06/2017','DD/MM/YYYY'), 'DAY') from dual;
returns
19.06.17
instead of expected
23.06.17?
We are on Oracle 11.

The DAY format returns the closest starting day of the week. Depending on your DB configuration, this might be a Sunday, Monday (in your case)...
You probably need the DD format instead.
Oracle doc

DAY truncates to closest SUNDAY [1]
you can use DD.
select trunc(to_date('23/06/2017','DD/MM/YYYY'), 'DD') from dual;

Your format is wrong, should be DD format:
select trunc(to_date('23/06/2017','DD/MM/YYYY'), 'DD') from dual;
Date Format Models for the ROUND and TRUNC Date Functions
DDD
DD
J
Day

Related

Create TimeStamp with fixed Time Part

What's the best way to get a timestamp that consists of the actual date but a fixed time part in oracle.
e.g.Today and always 09:00:00
2020-10-20 09:00:00
in MSSQL I would use FORMAT(GETDATE(),'yyyy-MM-dd 09:00:00')
Assuming you want a date rather than a varchar2, I'd use
trunc(sysdate) + interval '9' hour
trunc(sysdate) returns today at midnight and then interval '9' hour adds 9 hours to give you 9am. You can also add fractions of a day to a date so you could say
trunc(sysdate) + 9/24
I tend to find the interval notation more self-explanatory particularly if you're coming from a non-Oracle background.
You can use something like this:
SQL> alter session set NLS_DATE_FORMAT='YYYY-MM-DD';
Session altered.
SQL> set head off
SQL> select sysdate||' 09:00:00' from dual;
2020-10-19 09:00:00
Hope this is what you were looking for :)

convert date to order day of the month

How can I convert date to the order day of the month in ORACLE?
Ex: 31/07/2000 -> "Monday, the Thirty-First of July, 2000".
Is there any format date which can solve this problem?
Thanks so much!
Yes, there is - you need to combine some format elements (and modifiers) with a bit of boilerplate text (to add "the" and "of"). Like this:
select to_char( to_date('31/07/2000', 'dd/mm/yyyy')
, 'fmDay, "the " Ddspth "of" Month, yyyy') as spelled_out_date
from dual;
SPELLED_OUT_DATE
---------------------------------------
Monday, the Thirty-First of July, 2000
Note that, while the names of days of the week and calendar months depend on your session's then-current NLS_DATE_LANGUAGE, the Ddspth element will always be in English. So, alas, this solution DOES NOT WORK for other languages.

Date_part does not works in oracle

SELECT
DATE_PART('days',DATE_TRUNC('month', pr.DateTo) '1 MONTH'::INTERVAL - DATE_TRUNC('month', pr.datefrom) as PeriodDays
FROM HT_PayReg
This works well in postgres,but in oracle it does not works,Please correct it in oracle.
TRUNC gives the date excluding the time portion.
TO_CHAR with format mask gives you different parts of a date.
For example,
to_char(sysdate, 'DD') gives today's date as 09.
to_char(sysdate, 'MON') gives current month as OCT.
to_char(sysdate, 'YYYY') gives current year as 2014.
Play around with the different formats. For a specific output, mention your desired output.
Look at datetime format models in documentation here http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements004.htm

Subtract one hour from datetime rather than one day

I have a datetime column in Oracle (MM/DD/YYYY HH:MM:SS AM/PM) but when I do this:
SELECT MAX(D_DTM)-1 FROM tbl1
...it goes back a day. How do I remove one hour from the column rather than one day?
I've also noticed that the datetime records for 12AM look like MM/DD/YYYY and not MM/DD/YYYY 00:00:00; I'm not sure if that matters.
Randy's answer is good, but you can also use intervals:
SELECT MAX(D_DTM)- interval '1' hour FROM tbl1
yes - dates go by integer days.
if you want hours you need to do some math - like -(1/24)
Or use the INTERVAL function. It has the same result but I think it reads more clearly - that's of course just an opinion :)
SELECT MAX(D_DTM) - INTERVAL '1' HOUR FROM tbl1
The nice thing about the INTERVAL function is that you can make the interval be years, months, days, hours, minutes or seconds when dealing with a DATE value, though the month interval can be tricky when dealing with end-of-month dates.
And yes, the quote around the 1 in the example is required.
You can also use the Oracle-specific NumToDSInterval function, which is less standard but more flexible because it accepts variables instead of constants:
SELECT MAX(D_DTM) - NUMTODSINTERVAL(1, 'HOUR') FROM tbl1
select sysdate - numtodsinterval(1,'hour') from dual
Its simple.
sysdate - 5/(24*60*60) --> Subtracts 5 seconds from systime
sysdate - 5/(24*60) --> Subtracts 5 minutes from systime
sysdate - 5/(24) --> Subtracts 5 hours from systime
Hence
select (sysdate - (1/24)) from dual
Another method of using intervals is
NUMTODSINTERVAL( number, expression )
examples
NUMTODSINTERVAL(150, 'DAY')
NUMTODSINTERVAL(1500, 'HOUR')
NUMTODSINTERVAL(15000, 'MINUTE')
NUMTODSINTERVAL(150000, 'SECOND')
I bring this up because it is useful for situations where using INTERVAL wont work.

Oracle Interval Bug?

I'm using this sql query:
select sysdate, sysdate - INTERVAL '6' month from dual;
But it is return: ORA-01839: date not valid for month specified.
Which is weird, because if I change the the number into 9, it is return the date (sysdate = 31/05/11 and the subtracted is 31/08/10). I'm also tried using different value: 1,3,6,8,11 also not working, but 2,4,5,7,9,12 are working.
From the numbers, I think it is because the resulting quert doesn't have 31 days for that month. Is this the expected behavior? Because in MySQL, I can use the query (select now() - Interval 6 Month;) to get the correct value. Is there any other way?
I am using Oracle 11.1.0.6
It is the expected behaviour; see the sixth bullet in the datetime/interval arithmetic section of the documentation.
As Lisa says you can use add_months, which has the opposite behaviour - which can also cause confusion sometimes. You need to decide which is most suitable for you.
select sysdate,add_months(sysdate,-6) from dual;

Resources