I\'m trying to print for each person its age using this format :
E.g : 19 years , 8 months , 13 days.
I\'ve googled a lot and I\'ve noticed that there is a s
Very similar to Lalit's answer, but you can get an accurate number of days without assuming 30 days per month, by using add_months
to adjust by the total whole-month difference:
select sysdate,
hiredate,
trunc(months_between(sysdate,hiredate) / 12) as years,
trunc(months_between(sysdate,hiredate) -
(trunc(months_between(sysdate,hiredate) / 12) * 12)) as months,
trunc(sysdate)
- add_months(hiredate, trunc(months_between(sysdate,hiredate))) as days
from emp;
SYSDATE HIREDATE YEARS MONTHS DAYS
---------- ---------- ---------- ---------- ----------
2015-10-26 1980-12-17 34 10 9
2015-10-26 1981-02-20 34 8 6
2015-10-26 1981-02-22 34 8 4
2015-10-26 1981-04-02 34 6 24
2015-10-26 1981-09-28 34 0 28
2015-10-26 1981-05-01 34 5 25
2015-10-26 1981-06-09 34 4 17
2015-10-26 1982-12-09 32 10 17
2015-10-26 1981-11-17 33 11 9
2015-10-26 1981-09-08 34 1 18
2015-10-26 1983-01-12 32 9 14
2015-10-26 1981-12-03 33 10 23
2015-10-26 1981-12-03 33 10 23
2015-10-26 1982-01-23 33 9 3
You can verify by reversing the calculation:
with tmp as (
select trunc(sysdate) as today,
hiredate,
trunc(months_between(sysdate,hiredate) / 12) as years,
trunc(months_between(sysdate,hiredate) -
(trunc(months_between(sysdate,hiredate) / 12) * 12)) as months,
trunc(sysdate)
- add_months(hiredate, trunc(months_between(sysdate,hiredate))) as days
from emp
)
select * from tmp
where today != add_months(hiredate, (12 * years) + months) + days;
no rows selected
Getting the age in terms of YEARS and MONTHS is easy, but the tricky part is the the DAYS.
If you can fix the days in a month, you could get the number of days in the same SQL. For example, using the standard SCOTT.EMP table and assuming every month has 30
days:
SQL> SELECT SYSDATE,
2 hiredate,
3 TRUNC(months_between(SYSDATE,hiredate)/12) years,
4 TRUNC(months_between(SYSDATE,hiredate) -
5 (TRUNC(months_between(SYSDATE,hiredate)/12)*12)) months,
6 TRUNC((months_between(SYSDATE,hiredate) -
7 TRUNC(months_between(SYSDATE,hiredate)))*30) days
8 FROM emp;
SYSDATE HIREDATE YEARS MONTHS DAYS
---------- ---------- ---------- ---------- ----------
2015-10-26 1980-12-17 34 10 9
2015-10-26 1981-02-20 34 8 6
2015-10-26 1981-02-22 34 8 4
2015-10-26 1981-04-02 34 6 23
2015-10-26 1981-09-28 34 0 28
2015-10-26 1981-05-01 34 5 24
2015-10-26 1981-06-09 34 4 17
2015-10-26 1982-12-09 32 10 17
2015-10-26 1981-11-17 33 11 9
2015-10-26 1981-09-08 34 1 18
2015-10-26 1983-01-12 32 9 14
2015-10-26 1981-12-03 33 10 22
2015-10-26 1981-12-03 33 10 22
2015-10-26 1982-01-23 33 9 3
14 rows selected.
But, be aware not every month has 30
days. So, you cannot have the accuracy with number of days.
UPDATE
I missed the total whole-month difference which @Alex Poole has explained in his accepted answer. I will let this answer for future readers to understand the part that was missed about calculating the number of days.
Modify this:
TRUNC((months_between(SYSDATE,hiredate) -
TRUNC(months_between(SYSDATE,hiredate)))*30) days
With this:
TRUNC(SYSDATE) - add_months(hiredate, TRUNC(months_between(sysdate,hiredate)))
Another simplified way for getting months would be-
TRUNC(MOD(months_between(sysdate,hiredate),12)) AS months
Syntax:
SELECT
CONCAT(
TIMESTAMPDIFF(YEAR, ?, NOW()),
' Years,',
TIMESTAMPDIFF(MONTH, ?, NOW()) % 12,
' Months,',
FLOOR(TIMESTAMPDIFF(DAY, ?, NOW()) % 30.4375),
' Days'
) AS age
FROM
DUAL