Gossamer Forum
Home : Products : DBMan : Customization :

Date to Age

Quote Reply
Date to Age
Well, I'm having a little trouble with the script. I want to ask people for their birthday. Then I want to calculate their age. I wouldn't ask for their age directly as this will change with time. How can I do this. Do I have to add a new subroutine. I really don't know how dbman or unix handles dates. I would also want to add the age query to my search form, I guess this will be easy when I have a function that converts date of birth to age. Any clues?
Thanks in advance.
Quote Reply
Re: Date to Age In reply to
A lot depends on how your birthdate information is stored. If you can be sure that all of your visitors were born after 31-Dec-1969, you're okay. Otherwise you're going to have to make some other adjustments.

So that's what I need to know first. How are your birthdates stored?

Searching by age will be an interesting puzzle. Smile

------------------
JPD





Quote Reply
Re: Date to Age In reply to
Well, I didn't make adjustments to DBMan's date field. So I guess the format is 13-Sep-79 for example. You are right, I should change the 79 for 1979, as we're almost in the new century. What do I have to change for that? And how is age calculated from there?
Then, I've been thinking about the age-search. I have thought of allowing people to search between an age range. Then the program should transform each birthdate into an age and see if it's in the range. But I would only want these age fields to appear when people is searching, not adding records.

Another option would be to add an age field that would be hidden for users and filled in automatically by dbman when a record is added. Then, I thought that through the admin login there could be an option to go through the whole database updating all records, checking that ages have not changed. Wonder if this can be done. You're the expert.
Does this make sense? Please help me with my dbase.
Quote Reply
Re: Date to Age In reply to
I'm surprised that you can get a date like 13-Sep-79 from DBMan. Maybe you have an old version. Smile

Make sure your sub get_date in db.cgi has the line

$year = $year + 1900;

And, yes, that is Y2K compliant. Unix years are computed from the year 1900, so next year will be 100 as far as Unix is concerned.

Assuming that your birthdates are in the format of 13-Sep-1979, you can add a subroutine to db.cgi:

Code:
sub get_age {
# --------------------------------------------------------
my ($bdate) = $_[0];
my (%months) = ("Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3, "May" => 4, "Jun" => 5,
"Jul" => 6, "Aug" => 7, "Sep" => 8, "Oct" => 9, "Nov" => 10,"Dec" => 11);

my ($bday, $bmon, $byear) = split(/-/, $bdate);
my ($date) = &get_date();
my ($day, $mon, $year) = split(/-/, $date);

my ($age) = $year - $byear;
if ($months{$mon} < $months{$bmon}) {
--$age;
}
elsif (($months{$mon} == $months{$bmon}) && ($day < $bday)) {
--$age;
}
return $age;
}

Actually, this will work for people born before 1970.

If you want to print out the current age of the person use

print &get_age($rec{'Birthdate'});

Be sure it is not within a print statement. If you don't know what that means, ask. Smile

In order to search by age, you'll have to convert the age back into a birthdate. These will only work for people who were born after 31-Dec-1969.

Another couple of subroutines:

Code:
sub less_than_age {
my ($age) = $_[0];
my ($date) = &get_date(time + 86400);
my ($day, $mon, $year) = split(/-/, $date);
$year -= $age;
return "$day-$mon-$year";
}

Code:
sub greater_than_age {
my ($age) = $_[0];
my ($date) = &get_date();
my ($day, $mon, $year) = split(/-/, $date);
$year -= ++$age;
return "$day-$mon-$year";
}

Okay. Now to do the actual searching. Name your age fields Age-lt and Age-gt -- and be sure you do not have a field named "Age" in your database.

In sub query, after

local (%sortby);

add

Code:
if ($in{'Age-lt'}) {
$in{'Birthdate-gt'} = &less_than_age($in{'Age-lt'});
}

if ($in{'Age-gt'}) {
$in{'Birthdate-lt'} = &greater_than_age($in{'Age-gt'});
}

It seems odd, maybe, to be using Age-gt and Birthdate-lt, but that's the way it works if you think about it. (Maybe it seems natural to you, but I had to work a little to understand it myself. Smile )

There is no error-checking in these subroutines, but you shouldn't need them.

Oh. Don't forget to make the necessary changes to sub query regarding dates. If you haven't done it already, let me know and I'll post the changes you need to make again. Also, you may need to change sub get_date.

Oh, what the heck. I'll go ahead and post them in case you need them.

Replace sub get_date with the following:

Code:
sub get_date {
# --------------------------------------------------------
# Returns the date in the format "dd-mmm-yy".
# Warning: If you change the default format, you must also modify the &date_to_unix
# subroutine below which converts your date format into a unix time in seconds for sorting
# purposes.

$time = $_[0];
($time) &#0124; &#0124; ($time = time());

my ($sec, $min, $hour, $day, $mon, $year, $dweek, $dyear, $daylight) = localtime($time);
my (@months) = qw!Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec!;
($day < 10) and ($day = "0$day");
$year = $year + 1900;

return "$day-$months[$mon]-$year";
}

In sub query, make the changes indicated in bold print below:

Code:
if ($in{"$column-gt"} !~ /^\s*$/) { ($db_sort{$column} eq 'date') and
(&date_to_unix("$column-gt") or return qq|Invalid date format: '$in{"$column}-gt"'|);
push(@search_gt_fields, $i); }
if ($in{"$column-lt"} !~ /^\s*$/) { ($db_sort{$column} eq 'date') and
(&date_to_unix("$column-lt") or return qq|Invalid date format: '$in{"$column}-lt"'|);





------------------
JPD





Quote Reply
Re: Date to Age In reply to
Gosh, sorry I reply with my doubt in some sense late, but there's something I don't understand. Why do you specify 1970 as a barrier. I will be adding people that have been born after as well as before that date. How can I setup that. The rest of the post was understood, I guess
Thanks in advance.
Quote Reply
Re: Date to Age In reply to
I was wrong! Smile It does work for all ages. Possibly not for people born before 1900. (Just a sec. I'll test it.)

Works for them too!



------------------
JPD