For dates (i.e. times with h,m,s=0), it's better to use timegm+gmtime over timelocal+localtime. I think your program will return an incorrect answer for some time periods due to DST.
Update:
Solution which still uses core module Time::Local:
use strict;
use warnings;
use Time::Local qw( timegm_nocheck );
# birth_date_age(2006, 4, 28) for people born on April 28th, 2006.
sub birth_date_age {
my ($bday_y, $bday_m, $bday_d) = @_;
# ----------------------------------------
# -- Get current date.
my ($now_y, $now_m, $now_d) = (localtime)[5,4,3];
$now_y += 1900;
$now_m++;
my $date_now = timegm_nocheck(0,0,0, $now_d, $now_m-1, $now_y);
# ----------------------------------------
# -- Get next birthday.
my $date_next = timegm_nocheck(0,0,0, $bday_d, $bday_m-1, $now_y);
$date_next = timegm_nocheck(0,0,0, $bday_d, $bday_m-1, $now_y+1)
if $date_next <= $date_now;
my ($next_y) = (gmtime($date_next))[5];
$next_y += 1900;
# ----------------------------------------
# -- Get prev birthday.
my $prev_y = $next_y - 1;
my $date_prev = timegm_nocheck(0,0,0, $bday_d, $bday_m-1, $prev_y);
# ----------------------------------------
# -- Calculate age and others
my $age = $next_y - $bday_y - 1;
my $days_to = ($date_next - $date_now) / (24*60*60);
my $days_from = ($date_now - $date_prev) / (24*60*60);
return ($age, $days_from, $days_to);
}
Notes:
-
On years without a Feb 29th, March 1st will be considered the birthday anniversary of people born on Feb 29th.
-
I leave the date parsing to the caller. It makes for a more flexible solution.
-
For arguments, days, months and years are one-based.
-
Internally, days, months and years are one-based.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.