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 specific function to calculate the difference between dates DATEDIFF
.
However this function does not exist in SQL*Plus
, so I went on trying using MONTHS_BETWEEN()
and some operators.
My attempt:
SELECT name , ' ' ||
FLOOR(MONTHS_BETWEEN(to_date(SYSDATE),to_date(date_of_birth))/12)||' years ' ||
FLOOR(MOD(MONTHS_BETWEEN(to_date(SYSDATE),to_date(date_of_birth)),12)) || ' months ' ||
FLOOR(MOD(MOD(MONTHS_BETWEEN(to_date(SYSDATE),to_date(date_of_birth)),12),4))|| ' days ' AS "Age"
FROM persons;
My issue relies on getting the days. I don't know how should I calculate the days , using this function ('tried dividing by 4 , or 30); I'm thinking my logic is bad but I can't figure it out , any ideas ?
SELECT TRUNC((SYSDATE - TO_DATE(DOB, 'YYYY-MM-DD'))/ 365.25) AS AGE_TODAY FROM DUAL; This is easy and straight to the point. Save this answer.
We can find the age of a person from their date of birth by using this formula: SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(NOW(),'DATE_OF_BIRTH')), '%Y') + 0 AS age; In the above formula, we are first finding the difference between the current date (NOW()) and the date of birth (in YYYY-MM-DD) using the DATEDIFF() function.
Just use: select to_date(date_value, 'yyyy-mm-dd') as date_value from table; To convert to a date. That's it!
DECLARE @BirthDate datetime, @AgeInMonths int SET @BirthDate = '10/5/1971' SET @AgeInMonths -- Determine the age in "months old": = DATEDIFF(MONTH, @BirthDate, GETDATE()) -- . Get the difference in months - CASE WHEN DATEPART(DAY,GETDATE()) -- .
Simply subtract birth_date from sysdate : select id, (sysdate - birth_date) / 365 age from my_table; Subtracting dates results in the number of days, so dividing by 365 will give you decimal years.
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)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With