Calculate age based on date of birth

Small, short code snippets that other people may find useful. Do you have a good regex that you would like to share? Share it! Even better, the code can be commented on, and improved.

Moderator: General Moderators

User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Calculate age based on date of birth

Post by Benjamin »

Send date of birth in format YYYY-MM-DD

Code: Select all

function get_age($year, $month, $day) {
  if (date('m') - (int)$month >= 0) {
      if (date("d") - (int)$day >= 0 || date('m') > $month) {
          return date('Y') - (int)($year);
      }
  }
  return date('Y') - (int)($year) - 1;
}
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

you love stroring your dates in different formats don't you ;)
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

My thoughts exactly =).
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

With MySQL the query would be like:

Code: Select all

SELECT YEAR(CURRENT_DATE()) - YEAR(birthday) - (RIGHT(CURRENT_DATE(),5)<RIGHT(birthday,5)) AS age 
FROM foo;
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

Similar way.. :)

Code: Select all

function GetAge($DOB) {
	$birth = explode("-", $DOB);

	$age = date("Y") - $birth[0]; 

	if(($birth[1] > date("m")) || ($birth[1] == date("m") && date("d") < $birth[2]))
	{
		$age -= 1; 
	}
	return $age;
}
Man, I had to edit this this 3-4 times before I got it as small as I wanted. ;)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

The mighty timestamp would beat you all...:).
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

How does that work?
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

Maugrim_The_Reaper wrote:The mighty timestamp would beat you all...:).
Actually, it wouldn't. This could be a much better function:

Code: Select all

<?php
	function get_age($age)
	{
		$diff = time() - strtotime($age);


		return (int) ($diff / (3600 * 24 * 365));
	}
?>
The above function is more simple and can accept almost any date format. One problem though... A big problem... What about people who were born before 1.1.1970?
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Oren wrote:One problem though... A big problem... What about people who were born before 1.1.1970?
What about the extra remainders of the 365 days? leap years? timezones? :-P
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
Robert Plank
Forum Contributor
Posts: 110
Joined: Sun Dec 26, 2004 9:04 pm
Contact:

Post by Robert Plank »

This part doesn't make sense to me

Code: Select all

if ($DayDifference < 0 || $MonthDifference < 0) {
   $YearDifference--;
}
So if I'm born on May 21, 2005 and today is June 20, 2006 I should be 1 years old... but according to this I would be 0.

Please put intval()'s around your $Year, $Month, $Day, and date() values.
User avatar
Verminox
Forum Contributor
Posts: 101
Joined: Sun May 07, 2006 5:19 am

Post by Verminox »

One problem though... A big problem... What about people who were born before 1.1.1970?
Not really a problem, in PHP timestamps can be a negative integer to represent before 1970. Therefore, even if your string was something like "12 May 1944", then strtotime() would convert it to a negative timestamp and calculate the difference properly and you would get "62" years as the correct result.

As for timezones , they hardly matter when you are counting in terms of years.

To avoid the problem with leap years you can use 31556926 as the number of seconds in a year, and then calculate the value as a float (floor() it to make it an integer).

A modfiied version of Oren's function would be:

Code: Select all

function yearsSince($date){
		$date = is_string($date) ? strtotime($date) : $date;		
		$secondsSince = time() - $date;
		$secondsInAYear = 31556926;
		$yearsSince = floor($secondsSince / $secondsInAYear);
		return $yearsSince;
}
Which accepts dates as strings or unix timestamps and returns a more precise value.
Last edited by Verminox on Wed Jun 21, 2006 1:14 am, edited 3 times in total.
Robert Plank
Forum Contributor
Posts: 110
Joined: Sun Dec 26, 2004 9:04 pm
Contact:

Post by Robert Plank »

Verminox wrote:Not really a problem, in PHP timestamps can be a negative integer to represent before 1970.
Not in PHP 4
User avatar
Verminox
Forum Contributor
Posts: 101
Joined: Sun May 07, 2006 5:19 am

Post by Verminox »

Ahh I did not know that. Well so I guess PHP4 users will only have to deal with those younger than the age of 36 :P
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

Well, the one I posted works just fine. :)
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

scottayy wrote:What about the extra remainders of the 365 days? leap years?
I know, just didn't bother to mention that since the function isn't good anyway :wink:
Ohh and... I could be wrong, but time() returns seconds since 1.1.1970 so there shouldn't be any problems with leap years.
scottayy wrote:timezones? :P
Verminox wrote:As for timezones , they hardly matter when you are counting in terms of years.
Verminox wrote:Ahh I did not know that. Well so I guess PHP4 users will only have to deal with those younger than the age of 36 :P
I run PHP 5.1.4 and when I entered a date before 1.1.1970 the function returned 36, so I guess the negative timestamps don't work after all.
Post Reply