Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Compute a person's age today based on his date of birth.
#21
Neo and Deleter,

Check me out on the following:

I think the logic that both of you have at the end of the program where you finally compute the person's age, is a bit complicated. It has too many IF's.

They way I see it is as follows:

* We have done all the validations already, including that the date of birth is not in the future.

* Create a 4 byte variable called BMMDD$ which contains the month and day of the birth date.

* Create another 4 byte variable called CMMDD$ from the current date.

* We should already have a numeric variable called BYEAR for the year of the date of birth, and one called CYEAR for the year from the current date.


* Now we're ready to compute the AGE:
Code:
AGE = CYEAR - BYEAR
IF BMMDD$ < CMMDD$ THEN AGE = AGE - 1
You guys have been testing this problem much more than I, so tell me, will the above work? If not, why?

Thanks.
*****
Reply
#22
ShiftLynx,

Your solution looks quite complicate, but nevertheless I'll give it a shot as soon as I finish writing the test program.
*****
Reply
#23
well, I suppose that'd work, but technically, after validation, I am only using 2 more checks than you, all iside one IF statement, and I am too tired to rewrite the program right now because I just finished writing 2.6K words on an AI article.
[Image: freebasic.png]
Reply
#24
Hello Moneo,

Quote:I think the logic that both of you have at the end of the program where you finally compute the person's age, is a bit complicated. It has too many IF's.
I don't believe so. It only contains 1 IF, and 3 lines.
Here is the part of my code that calculates a persons age:
Code:
Private Function getPersonAge (Year As Integer, Month As Integer, Day As Integer, _
                               NowYear As Integer, NowMonth As Integer, NowDay As Integer) As Integer    
    If (NowMonth > Month) Or (NowMonth = Month And NowDay >= Day) Then getPersonAge = NowYear - Year Else getPersonAge = NowYear - Year - 1
End Function

Quote:* We have done all the validations already, including that the date of birth is not in the future.
Yes. Which is why the age calculation can be done in 1 line (see function above).


Quote:* Create a 4 byte variable called BMMDD$ which contains the month and day of the birth date.

* Create another 4 byte variable called CMMDD$ from the current date.

* We should already have a numeric variable called BYEAR for the year of the date of birth, and one called CYEAR for the year from the current date.


* Now we're ready to compute the AGE:
Code:
AGE = CYEAR - BYEAR
IF BMMDD$ < CMMDD$ THEN AGE = AGE - 1
You guys have been testing this problem much more than I, so tell me, will the above work? If not, why?
The code you provided will not work, as it would return an age too high if the birthday hasn't passed yet, and an age too low if the birthday already passed. This flaw will be fixed if the < is turned into a >.
Your code is the same as mine in general, only you need more lines for converting the dates to the appropriate string format.

Smile Thanks for checking. (Although it seems you didn't test the code I supplied you with the last time, which is also displayed in this post of mine).
Reply
#25
(see next edited post.................)
Reply
#26
Quote:
Neo Wrote:...
The code you provided will not work, as it would return an age too high if the birthday hasn't passed yet, and an age too low if the birthday already passed. This flaw will be fixed if the < is turned into a >.
Neo,
You're absolutely right. The compare should be:
Code:
IF BMMDD$  > CMMDD$ THEN AGE = AGE - 1
A comment should be added saying: "At this point, the current year is included in the AGE. If the birthday has not happened yet in the current year, then adjust the AGE down by one year so as to exclude the current year from the age. By the same token, if the birthday has passed, or we are exactly on it, then the age is correct as is."

Neo, now that you've debugged my logic, I'm going to use this in the test program. Let's see whaat happens when we run your solution and also Deleter's in a test of about 100 years worth of birthdays.
*****
Reply
#27
Deleter,

I tested yours first since, of the final versions, yours was posted first.

The test program runs through every day from 19000101 to 20051231.

The answer of AGE which you compute is compared to the one I compute. They all match except a few shown below.

The first column is the Current Date used.
The second column is the Birth Date being processed.
The third coumn is the AGE that I compute.
The fourth column is the AGE you compute.

Only records with differences in AGE are displayed.
Code:
CurDate=06-11-2005  BirDate= 2000 0130   5              -1
CurDate=06-11-2005  BirDate= 2000 0131   5              -1
CurDate=06-11-2005  BirDate= 2000 0330   5              -1
CurDate=06-11-2005  BirDate= 2000 0331   5              -1
CurDate=06-11-2005  BirDate= 2000 0430   5              -1
CurDate=06-11-2005  BirDate= 2000 0530   5              -1
CurDate=06-11-2005  BirDate= 2000 0531   5              -1
CurDate=06-11-2005  BirDate= 2000 0630   4              -2
CurDate=06-11-2005  BirDate= 2000 0730   4              -2
CurDate=06-11-2005  BirDate= 2000 0731   4              -2
CurDate=06-11-2005  BirDate= 2000 0830   4              -2
CurDate=06-11-2005  BirDate= 2000 0831   4              -2
CurDate=06-11-2005  BirDate= 2000 0930   4              -2
CurDate=06-11-2005  BirDate= 2000 1030   4              -2
CurDate=06-11-2005  BirDate= 2000 1031   4              -2
CurDate=06-11-2005  BirDate= 2000 1130   4              -2
CurDate=06-11-2005  BirDate= 2000 1230   4              -2
CurDate=06-11-2005  BirDate= 2000 1231   4              -2

As you can see, only a few failed, and they're all in the year 2000, which was a leapyear. Check it out and submit a fix.
*****
Reply
#28
Neo,

I ran a test from 19000101 to 20051231 with current date of 20051231, and you solution ran perfectly. Congratulations!

After I test Lynx's entry, a winner will be announced.
*****
Reply
#29
SHIFTLYNX,

I did some initial tests today June 11th on your code of June 10th, I found the following anomalies:

1) With a date of birth of 20040611 it issues an age of 0, which should be 1.

2) With a date of birth of 20040610 it also issues an age of 0, which should be 1.

However, with a date of birth of 20040609 it issues years of 1, which is correct.

I suspect that the problem is your use of 365.25 average days in your calculations. But, test it yourself.

I'll wait a few days for your revised solution.
*****
Reply
#30
ok, the error was in the check for the leap year every 400 that overrides the 100 rule. Fixed code:
Code:
declare function maxday(month as integer, year as integer)

print "Type 'X' to exit"
do
    input$ "Birthdate (YYYYMMDD)", birth$
    if ucase$(left$(birth$, 1)) = "X" then exit do
    cdate$ = date$
    cyear = val(mid$(cdate$, 7, 4))
    cmonth = val(mid$(cdate$,1,2))
    cday = val(mid$(cdate$, 4, 2))
    byear = val(mid$(birth$, 1, 4))
    bmonth = val(mid$(birth$, 5,2))
    if bmonth < 1 or bmonth > 12 then byear = cyear+1
    bday = val(mid$(birth$,7,2))
    if bday < 1 or bday > maxday(bmonth, byear) then byear = cyear+1
    age = (cyear - byear) - 1
    if (bmonth <= cmonth) and (bday <= cday or bmonth < cmonth) then
            age = age + 1
    end if
    if byear < 0 then byear = cyear+1
    if age < 0 then
        print "Invalid birthdate"
    elseif age < 1 then
        print cmonth-bmonth; " months old"
    elseif age = 1 then
        print age; " year old"
    elseif age > 1 then
        print age; " years old"
    end if    
loop
end

function maxday(month as integer, year as integer)
    tmaxday = 30
    if (month/2 <> int(month/2) and month < 8) or (month>7 and month/2 = int(month/2)) then tmaxday=31
    if month=2 and ((year mod 4 <> 0) or (year mod 100 = 0)) then tmaxday=28
    if (((month=2 and year mod 4 = 0) and year mod 100 <> 0) or (year mod 400 = 0 and month=2))=-1 then tmaxday = 29
    maxday=tmaxday
end function
[Image: freebasic.png]
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)