Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Calculating a persons age based on their birthday.

by artful (Initiate)
on May 03, 2000 at 02:49 UTC ( #9995=perlquestion: print w/replies, xml ) Need Help??

artful has asked for the wisdom of the Perl Monks concerning the following question:

I need to calculate someone's age based on their birthday. The birthday is being pulled from MySQL so I have the FROM_DAYS() function which will give me the number of days they have been alive. I cannot just divide by 365 because of leap years and all. Any advice on accurately calculating someone's age?
  • Comment on Calculating a persons age based on their birthday.

Replies are listed 'Best First'.
Re: Calculating a persons age based on their birthday.
by cciulla (Friar) on May 03, 2000 at 03:19 UTC
    Check out Date::Calc at CPAN.

    The following code was shamelessly copied from Date::Calc's documentation:

    use Date::Calc qw( Decode_Date_EU Today leap_year Delta_Days ); $date = <STDIN>; # get birthday ($year1,$month1,$day1) = Decode_Date_EU($date); ($year2,$month2,$day2) = Today(); if (($day1 == 29) && ($month1 == 2) && !leap_year($year2)) { $day1--; } if ( (($year2 - $year1) > 18) || ( (($year2 - $year1) == 18) && (Delta_Days($year2,$month1,$day1, $year2,$month2,$day2) >= 0) ) ) { print "Ok - you are over 18.\n"; } else { print "Sorry - you aren't 18 yet!\n"; }
Re: Calculating a persons age based on their birthday.
by buzzcutbuddha (Chaplain) on May 03, 2000 at 15:50 UTC
    IMHO a better way to tell if someone's age in years is to calc this way:
    use integer; # speeds up the math my @date = localtime(time); # convert year to months and add current number of months my $yearnow = ((($date[5] + 1900) * 12) + ($date[4] + 1)); print "Enter an 8 digit birthdate. eg: 01/01/1970\n"; my ($monththen, $daythen, $yearthen) = split /\//, <STDIN>; # we'll fly without error-checking now and just add what they e +ntered for month my $modyearthen = (($yearthen * 12) + ($monththen)); # subtract the totals and divide by 12, convert to int (redunda +nt for safety sake) # and voila actual number of years alive $numyears = int (($yearnow - $modyearthen)/12); print "You've been around $numyears years!\n";

    This way, you are also accounting for the months. For example, I was born in
    August, and if you just subtract the years from each other right now, it says I'm 25,
    which isn't right. You need to account for the total number of months, and then take
    the integer part of the division by 12 which gives you the year and remainder. It's more
    work, but it's a hair more accurate. Certainly for the sake of accuracy, you could take
    it down to days...but I'll leave that to someone else! :)
RE: Calculating a persons age based on their birthday.
by Simplicus (Monk) on May 03, 2000 at 20:20 UTC
    If all you want is the "year value" of a person's age, you
    could divide by 365, after you added one to the number
    of days for each of the leap years since the person's birth.
    You could calculate this offset by subtracting their
    birth year from the current year and dividing the result by
    four. This works becuase they can't have been born both
    before and after Feb 29th. Something like:
    use integer; #...code ommited; obtain $days from FROM_DAYS() # and $birth_year from database my $this_year; my @time; my $raw_years; my $num_leaps; my $int_years; my $float_years; @time = localtime(time); $this_year = $time[5] + 1900; $raw_years = $this_year - $birth_year; $num_leaps = $raw_years / 4; $days += $num_leaps; $int_years = $days / 365; no integer; $float_years = $days / 365; if ($int_years == $float_years) { print "Today's your birthday!"; } #...Then do whatever else you're going to do
    I used a few more variable declarations than I would normally
    but I wanted to clarify what I was doing. It's
    quick and dirty, but probably works...
    Simplicus
      If you want to be slightly more accurate (not that this matters for another 100 years, but hey!) the leap year formula is that a leap year is divisable by 4, but not 100 (except if divisable by 400). Of course, the amount of error induced by leap years wouldn't effect your program unless the person was over a thousand years old (one day of error every four years would take a long time to become relevant), otherwise its safe to just div by 365.

      Article about leap years.

        I'm not sure how clear I was in the previous post. I was rather tired and stuff. The original question was:

        I need to calculate someone's age based on their birthday. The birthday is being pulled from MySQL so I have the FROM_DAYS() function which will give me the number of days they have been alive. I cannot just divide by 365 because of leap years and all. Any advice on accurately calculating someone's age?

        So I was trying to say that leap years are irrelevant. You have the birth date. So you just divide the number of days by 365. This will be off by one day every four years, meaning that their birthday will appear to creep at the rate of 6 hours a year. This shouldn't be a big deal though... it just means that their birthday will move forward a day every four years. This means that if a person enters a birth date for an age verification system, it would let them by 4 days before their 18th birthday or 5 days before their 21st. In almost any other application, the error is negligable.
Re: Calculating a persons age based on their birthday.
by btrott (Parson) on May 03, 2000 at 03:13 UTC
    Well, what exactly are you looking for? Something like "I've been alive 10 years", or "I've been alive 10.6293 years"? :) Or "I've been alive 10 years, 7 months, etc."?

    Take a look at Date::Calc and Date::Manip.

      I was just looking for the number of years alive. So like when their birthday rolls around I can say happy birthday your 10 years old. Or hey everyone John Doe is 10 years old today.
        Date::Calc (or, heaven forbid, Date::Manip) is probably overkill since you only want age in years. All you really want to know is whether the birthday has passed this year.
        sub age { # Assuming $birth_month is 0..11 my ($birth_day, $birth_month, $birth_year) = @_; my ($day, $month, $year) = (localtime)[3..5]; $year += 1900; my $age = $year - $birth_year; $age-- unless sprintf("%02d%02d", $month, $day) >= sprintf("%02d%02d", $birth_month, $birth_day); return $age; }
        Of course, if you're only using this on a person's birthday, all you need to do is subtract their birth year from the current year :-)
Re: Calculating a persons age based on their birthday.
by Maqs (Deacon) on May 03, 2000 at 14:12 UTC
    As far as I understand, you would like to know the number of full years the person is alive?
    So, assuming you have only the number of day, we can do the following:
    ---
    my $year = (localtime)[5]+1900;
    my $fullyears=0;
    $nod = xxxx; #number of days goes here...
    while ($nod > 365)
    { if ( $year % 4) {$nod=$nod-365} else {$nod=$nod-366}; #check for the leap year.
    $year--; $fullyears++;
    };

    print "$fullyears\n";
    ---
    Rather simple but m.b. not so gracefull solution :) You see, you do not need any special modules.
      Sholdn't the
      if ($year % 4) {$nod=$nod-365} else {$nod=$nod-366}; #check for the le +ap year.
      be
      if ((($year % 4 == 0) && ($year % 100 != 0)) || ($year % 400) == 0) {$ +nod=$nod-365} else {$nod=$nod-366}; #check for the leap year.
      To handle Y2K (and others) correct... /t0mas
        Sorry - It should be
        if ((($year % 4 == 0) && ($year % 100 != 0)) || ($year % 400) == 0) {$ +nod=$nod-366} else {$nod=$nod-365}; #check for the leap year.
        365 and 366 swiched places....

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://9995]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2022-07-01 23:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My most frequent journeys are powered by:









    Results (102 votes). Check out past polls.

    Notices?