Reputation: 999
I got problem using FROM_DAYS
function in mysql, i want to get age from my_table, here's my query;
select dob,CURRENT_DATE,
DATE_FORMAT(FROM_DAYS(DATEDIFF(CURRENT_DATE,dob)),'%y yr %c mth %e dy') AS age,
DATEDIFF(CURRENT_DATE,dob) days from my_table
result:
dob || CURRENT_DATE || age || days ||
==========++==============++==================++=======++
1953-09-10|| 2013-09-12 || 60 yr 1 mth 3 dy || 21917 ||
2013-09-08|| 2013-09-12 || 00 yr 0 mth 0 dy || 4 ||
when I tried FROM_DAYS(DATEDIFF(CURRENT_DATE,m.tgllahir))
for 2nd row this is the result 0000-00-00
and then I tried looking at Date and Time Functions and found this
SELECT FROM_DAYS(730669);
-> '2007-07-03'
but when I tried this is what I got;
SELECT FROM_DAYS(730669);
-> '2000-07-03'
I'm curious why FROM_DAYS
function not working properly, but my main problem is how to find the age?
EDIT
after a discussion with Barmar I know that I can't use FROM_DAYS to get accurate age, so I tried to find different method
Upvotes: 0
Views: 11500
Reputation: 11
I prefer using function.
This is the DDL of my function. This function is accurate and more precise.
DELIMITER $$
DROP FUNCTION IF EXISTS f_age $$
CREATE FUNCTION `f_age`(
x_dob DATE
)
RETURNS varchar(100) CHARSET latin1
NOT DETERMINISTIC
CONTAINS SQL
BEGIN
DECLARE x_result VARCHAR(100);
DECLARE y1, y2, m1, m2, d1, d2 INT;
DECLARE x1, x2 DATE;
SET x_result = "";
SET x1 = x_dob;
SET x2 = CURDATE();
IF (x1 < x2) THEN
SET y1 = DATE_FORMAT(x1, '%Y');
SET m1 = DATE_FORMAT(x1, '%c');
SET d1 = DATE_FORMAT(x1, '%e');
SET y2 = DATE_FORMAT(x2, '%Y');
SET m2 = DATE_FORMAT(x2, '%c');
SET d2 = DATE_FORMAT(x2, '%e');
IF (d1 > d2) THEN
SET m2 = m2 - 1;
IF (m2 = 0) THEN
SET y2 = y2 - 1;
SET m2 = 12;
END IF;
SET d2 = d2 + DAY(LAST_DAY(CONCAT_WS("-", y2, m2, d2)));
END IF;
IF (m1 > m2) THEN
SET y2 = y2 - 1;
SET m2 = m2 + 12;
END IF;
IF (y2 > y1) THEN
SET x_result = CONCAT((y2 - y1), ' yr ');
END IF;
IF ((y2 > y1) OR (m2 > m1)) THEN
SET x_result = CONCAT(x_result, CONCAT((m2 - m1), ' mth '));
END IF;
IF ((y2 > y1) OR (m2 > m1) OR (d2 > d1)) THEN
SET x_result = CONCAT(x_result, CONCAT((d2 - d1), ' dy'));
END IF;
ELSE
SET x_result = "Error. Date of birth is today or more than today";
END IF;
RETURN x_result;
END $$
DELIMITER ;
Than, here is code to use the function:
SELECT f_age(dob) FROM table;
It also handle leap year accurately
Upvotes: 0
Reputation: 21
SELECT FLOOR(( DATE_FORMAT(NOW(),'%Y%m%d') - DATE_FORMAT(t.dob,'%Y%m%d'))/10000) AS years,
FLOOR((1200 + DATE_FORMAT(NOW(),'%m%d') - DATE_FORMAT(t.dob,'%m%d'))/100) %12 AS months,
(SIGN(DAY(NOW()) - DAY(t.dob))+1)/2 * (DAY(NOW()) - DAY(t.dob)) +
(SIGN(DAY(NOW()) - DAY(t.dob))+1)/2 * (DAY(NOW()) - DAY(t.dob)) +
(SIGN(DAY(t.dob) - DAY(NOW()))+1)/2 * (DAY(STR_TO_DATE(DATE_FORMAT(t.dob + INTERVAL 1 MONTH,'%Y-%m-01'),'%Y-%m-%d') - INTERVAL 1 DAY) - DAY(t.dob) + DAY(NOW())) AS days
FROM tablename t
try this query
Upvotes: 2
Reputation: 9
To Use the FROM_DAYS() function and get the age of the person in the format you are looking for you must simply add a function to get the years months or days like so
CONCAT(
YEAR(FROM_DAYS(DATEDIFF(NOW(),*DB LOCATION*))),' years,',
MONTH(FROM_DAYS(DATEDIFF(NOW(),*DB LOCATION*))),' months,',
DAY(FROM_DAYS(DATEDIFF(NOW(),*DB LOCATION*))),' days,',)
Upvotes: 0
Reputation: 4263
This is a query I use to calculate age in years, months and days:
SELECT
username
,dob
,DATE_FORMAT(CURDATE(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(CURDATE(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS years
,PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(dob, '%Y%m') ) AS months
,DATEDIFF(CURDATE(),dob) AS days
FROM users
Upvotes: 0