Qbasicnews.com
September 18, 2019, 08:58:20 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: 1 [2] 3
  Print  
Author Topic: Compute a person's age today based on his date of birth.  (Read 17836 times)
Neo
Na_th_an
*****
Posts: 2150



« Reply #15 on: June 10, 2005, 04:15:54 PM »

Sorry moneo, final update.

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


this is the simplest (at least) functional code I could think of.

I now did it in all 3 possible ways...
- Using a loop: will return the correct results, except from leaplings
- Using average calculation: will mostly return correct results and sometimes return ages that are +1 or -1
- Using conditional checks: will probably (only tested 80000 times yet) return correct results, including leaplings.

Now I'll be quiet so you can have the time to check these 3 Smiley (I'm pretty sure the latest 3-liner update can't be shortened anymore).

I apologize for another piece of code. This is my last submission (and probably the best working one too... :roll:).
Logged
shiftLynx
Wandering Guru
***
Posts: 340



WWW
« Reply #16 on: June 10, 2005, 05:04:41 PM »

Written in FreeBASIC; should work in QBASIC.

[syntax="QBasic"]
' Current Age Calculator
' 10-Jun-2005
'
' shiftlynx
' c.g.davies@gmail.com
'

'-----------------------------------------------------------------------------
' Custom Type Declarations
'
type Date
    year as integer
    month as integer
    day as integer
end type

'-----------------------------------------------------------------------------
' Function Declarations
'
declare sub parseDate(dateString as string, target as Date)
declare sub parseDashedDate(dateString as string, target as Date)
declare function isValidDate%(obj as Date)
declare function getDays&(obj as Date)

'-----------------------------------------------------------------------------
' Main
'
dim dateIn as Date
dim dateCurrent as Date
dim dayDifference as long
dim age as long

cls
line input "Date of Birth: ", strdate$

' parse the date strings.
parseDate(strdate$, dateIn)
parseDashedDate(date$, dateCurrent)

' validate the dates.
if isValidDate%(dateIn) = 0 then
    print "Invalid date entered."
    end
end if

if isValidDate%(dateCurrent) = 0 then
    print "Failed to parse current date."
    end
end if

' calculate the day difference.
dayDifference = getDays&(dateCurrent) - getDays&(dateIn)

' make sure the date entered wasn't in the future.
if dayDifference < 0 then
    print "Invalid date of birth; it hasn't happened yet."
    end
end if

' calculate the number of complete years.
age = int(dayDifference / 365.25)

' output the age.
print "Age: " + ltrim$(str$(age))

print "Press a key to exit..."
while inkey$ = "": wend



sub parseDate(dateString as string, target as Date)
   
    ' reset the structure.
    target.day = 0
    target.month = 0
    target.year = 0
   
    ' check that we have a valid length (must be YYYYMMDD).
    if len(dateString) <> 8 then exit sub
   
    ' extract the components.
    target.year = val(mid$(dateString, 1, 4))
    target.month = val(mid$(dateString, 5, 2))
    target.day = val(mid$(dateString, 7, 2))
   
end sub



sub parseDashedDate(dateString as string, target as Date)
   
    ' reset the structure.
    target.day = 0
    target.month = 0
    target.year = 0
   
    ' just make sure that the length of the date isn't too small.
    ' smallest date... x/x/xxxx = 8 chars.
    if len(dateString) < 8 then exit sub
   
    ' store a "working-string".
    tempStr$ = dateString
   
    ' extract the month.
    slash% = instr(tempStr$, "-")
    if slash% > 0 then
        target.month = val(left$(dateString, slash% - 1))
        tempStr$ = right$(tempStr$, len(tempStr$) - slash%)
    else
        exit sub
    end if
   
    ' extract the day.
    slash% = instr(tempStr$, "-")
    if slash% > 0 then
        target.day = val(left$(tempStr$, slash% - 1))
        tempStr$ = right$(tempStr$, len(tempStr$) - slash%)
    else
        exit sub
    end if
   
    ' extract the year.
    target.year = val(tempStr$)
   
end sub



function isValidDate%(obj as Date)
   
    ' check for obvious errors.
    if obj.day < 1 or obj.day > 31 or obj.month < 1 or obj.month > 12 or obj.year < 0 then
        isValidDate% = 0
        exit function
    end if
   
    ' now check specific errors.
    select case obj.month
        case 2:
            if (obj.year and 3) = 0 then
                if obj.day > 29 then
                    isValidDate% = 0
                    exit function
                end if
            else
                if obj.day > 28 then
                    isValidDate% = 0
                    exit function
                end if
            end if
        case 4, 6, 9, 11:
            if obj.day > 30 then
                isValidDate% = 0
                exit function
            end if
    end select
   
    ' looks okay.
    isValidDate% = 1
   
end function



function getDays&(obj as Date)
   
    dim cumulativeMonthDays(1 to 12) as long
   
    ' ensure we're dealing with a valid date.
    if isValidDate%(obj) = 0 then
        getDays& = -1
        exit function
    end if
   
    ' calculate the days from the year and the day.
    days& = int(obj.year * 365.25) + obj.day
   
    ' now to process the month field...
   
    ' check if we need to account for an extra day in February.
    if (obj.year and 3) = 0 then
        dayCount& = 1
    else
        dayCount& = 0
    end if
   
    ' set up the month days array.
    cumulativeMonthDays(1) = 0
    dayCount% = dayCount& + 31 ' jan
    cumulativeMonthDays(2) = 31
    dayCount& = dayCount& + 28 ' feb
    cumulativeMonthDays(3) = dayCount&
    dayCount& = dayCount& + 31 ' mar
    cumulativeMonthDays(4) = dayCount&
    dayCount& = dayCount& + 30 ' apr
    cumulativeMonthDays(5) = dayCount&
    dayCount& = dayCount& + 31 ' may
    cumulativeMonthDays(6) = dayCount&
    dayCount& = dayCount& + 30 ' jun
    cumulativeMonthDays(7) = dayCount&
    dayCount& = dayCount& + 31 ' jul
    cumulativeMonthDays(Cool = dayCount&
    dayCount& = dayCount& + 31 ' aug
    cumulativeMonthDays(9) = dayCount&
    dayCount& = dayCount& + 30 ' sep
    cumulativeMonthDays(10) = dayCount&
    dayCount& = dayCount& + 31 ' oct
    cumulativeMonthDays(11) = dayCount&
    dayCount& = dayCount& + 30 ' nov
    cumulativeMonthDays(12) = dayCount&
   
    ' now add the month days on to the day total.
    days& = days& + cumulativeMonthDays(obj.month)
   
    ' set the return value.
    getDays& = days&
   
end function
[/syntax]
Logged

img]http://www.cdsoft.co.uk/misc/shiftlynx.png[/img]
Deleter
Na_th_an
*****
Posts: 1292



WWW
« Reply #17 on: June 10, 2005, 05:31:38 PM »

ok, extra chopped off, definition of leap year corrected and its ready to roll (I hope Smiley )
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))=-1 then tmaxday = 29
    maxday=tmaxday
end function

edit: added if statment to make sure year was greater than or equal to 0
Logged

Neo
Na_th_an
*****
Posts: 2150



« Reply #18 on: June 10, 2005, 07:22:01 PM »

Okay, as everyone is posting new updates, I put my latest updates together in one file, ready for execution.

Code:
Option Static
Option Explicit

Declare Function convertDate (Dat As String, YY As Integer, MM As Integer, DD As Integer) As Byte
Declare Function isValidDate (Year As Integer, Month As Integer, Day As Integer) As Byte
Declare Function isLeapYear (Year As Integer) As Byte
Declare Function getPersonAge (Year As Integer, Month As Integer, Day As Integer, _
                               NowYear As Integer, NowMonth As Integer, NowDay As Integer) As Integer

'@ Ask the user for input YYYYMMDD and check if it's valid
Dim Datum As String, isOk As Byte
Dim Year As Integer, Month As Integer, Day As Integer
Do
    Input "Enter a valid birthday in format YYYYMMDD: ", Datum    
    isOk = convertDate(Datum, Year, Month, Day)      
    If Not( isOk ) Then Print "Invalid entry"
Loop Until isOk

'@ Get the current Date (format MM-DD-YYYY)
Dim CurrYear As Integer, CurrMonth As Integer, CurrDay As Integer
If convertDate(Date$, CurrYear, CurrMonth, CurrDay) = 0 Then Print "Current date is invalid": End

'@ Get persons age and print it
Dim rAge As Integer
rAge = getPersonAge(Year, Month, Day, CurrYear, CurrMonth, CurrDay)
If rAge > 0 Then
    Print "Persons age: "; rAge
Else
    If Year > CurrYear Or (Year = CurrYear And Month > CurrMonth) Or (Year = CurrYear And Month = CurrMonth And Day > CurrDay) Then
        Print "This person is yet to be born"
    Else
        Print "Persons age: "; rAge
    End If    
End If

Sleep
End


Private Function convertDate (Dat As String, YY As Integer, MM As Integer, DD As Integer) As Byte
    Dim NumberStr As String , i As Integer
    NumberStr = "0123456789"
    If Len(Dat) <> 8 And Len(Dat) <> 10 Then
        convertDate = 0: Exit Function
    ElseIf Len(Dat) = 8 Then
        For i = 0 To 7
            If Instr(NumberStr, Mid$(Dat, i + 1, 1)) = 0 Then convertDate = 0: Exit Function
        Next i                
        YY = Val(Left$(Dat, 4))
        MM = Val(Mid$(Dat, 5, 2))
        DD = Val(Right$(Dat, 2))            
        convertDate = isValidDate(YY, MM, DD)
    ElseIf Len(Dat) = 10 Then
        For i = 0 To 9
            If i = 2 Or i = 5 Then
                If Mid$(Dat, i + 1, 1) <> "-" Then convertDate = 0: Exit Function
            Else
                If Instr(NumberStr, Mid$(Dat, i + 1, 1)) = 0 Then convertDate = 0: Exit Function
            End If            
        Next i        
        YY = Val(Right$(Dat, 4))
        MM = Val(Left$(Dat, 2))
        DD = Val(Mid$(Dat, 4, 2))
        convertDate = isValidDate(YY, MM, DD)
    End If  
End Function


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

Private Function isValidDate (Year As Integer, Month As Integer, Day As Integer) As Byte
    '@ Checks if a year is a valid year
    If Year < 0 Then isValidDate = 0: Exit Function
    If Month < 1 Then isValidDate = 0: Exit Function
    If Day < 1 Then isValidDate = 0: Exit Function
   
    If Month > 12 Then isValidDate = 0: Exit Function
   
    Dim MaxDay As Integer
    Select Case Month
        Case 1, 3, 5, 7, 8, 10, 12 : MaxDay = 31
        Case 4, 6, 9, 11: MaxDay = 30        
        Case 2: MaxDay = 28 + Abs(isLeapYear(Year))        
    End Select    
   
    If Day > MaxDay Then isValidDate = 0: Exit Function
   
    isValidDate = -1
End Function

Private Function isLeapYear (Year As Integer) As Byte
    isLeapYear = ((Year MOD 4 = 0) AND (Year MOD 100 <> 0)) OR (Year MOD 400 = 0)
End Function




And shiftLynx... also for you holds the same as I said to Deleter a while ago Smiley
Quote from: "WikiPedia"
The Gregorian calendar adds an extra day to February, making it 29 days long, in years where the quotient has no remainder when divided by 4, excluding years where the quotient has no remainder when divided by 100, but including years where the quotient has no remainder when divided by 400.
Logged
shiftLynx
Wandering Guru
***
Posts: 340



WWW
« Reply #19 on: June 10, 2005, 07:42:11 PM »

[syntax="QBasic"]
' Current Age Calculator
' 10-Jun-2005
'
' shiftlynx
' c.g.davies@gmail.com
'
' Changes:
'   [10-Jun-2005]       Fixed leap-year calculation algorithm... turns out
'                       to be a bit more complicated then just "mod 4".
'

'-----------------------------------------------------------------------------
' Custom Type Declarations
'
type Date
    year as integer
    month as integer
    day as integer
end type

'-----------------------------------------------------------------------------
' Function Declarations
'
declare sub parseDate(dateString as string, target as Date)
declare sub parseDashedDate(dateString as string, target as Date)
declare function isValidDate%(obj as Date)
declare function getDays&(obj as Date)
declare function isLeapYear%(year as integer)

'-----------------------------------------------------------------------------
' Main
'
dim dateIn as Date
dim dateCurrent as Date
dim dayDifference as long
dim age as long

cls
line input "Date of Birth: ", strdate$

' parse the date strings.
parseDate(strdate$, dateIn)
parseDashedDate(date$, dateCurrent)

' validate the dates.
if isValidDate%(dateIn) = 0 then
    print "Invalid date entered."
    end
end if

if isValidDate%(dateCurrent) = 0 then
    print "Failed to parse current date."
    end
end if

' calculate the day difference.
dayDifference = getDays&(dateCurrent) - getDays&(dateIn)

' make sure the date entered wasn't in the future.
if dayDifference < 0 then
    print "Invalid date of birth; it hasn't happened yet."
    end
end if

' calculate the number of complete years.
age = int(dayDifference / 365.25)

' output the age.
print "Age: " + ltrim$(str$(age))

print "Press a key to exit..."
while inkey$ = "": wend



sub parseDate(dateString as string, target as Date)
   
    ' reset the structure.
    target.day = 0
    target.month = 0
    target.year = 0
   
    ' check that we have a valid length (must be YYYYMMDD).
    if len(dateString) <> 8 then exit sub
   
    ' extract the components.
    target.year = val(mid$(dateString, 1, 4))
    target.month = val(mid$(dateString, 5, 2))
    target.day = val(mid$(dateString, 7, 2))
   
end sub



sub parseDashedDate(dateString as string, target as Date)
   
    ' reset the structure.
    target.day = 0
    target.month = 0
    target.year = 0
   
    ' just make sure that the length of the date isn't too small.
    ' smallest date... x/x/xxxx = 8 chars.
    if len(dateString) < 8 then exit sub
   
    ' store a "working-string".
    tempStr$ = dateString
   
    ' extract the month.
    slash% = instr(tempStr$, "-")
    if slash% > 0 then
        target.month = val(left$(dateString, slash% - 1))
        tempStr$ = right$(tempStr$, len(tempStr$) - slash%)
    else
        exit sub
    end if
   
    ' extract the day.
    slash% = instr(tempStr$, "-")
    if slash% > 0 then
        target.day = val(left$(tempStr$, slash% - 1))
        tempStr$ = right$(tempStr$, len(tempStr$) - slash%)
    else
        exit sub
    end if
   
    ' extract the year.
    target.year = val(tempStr$)
   
end sub



function isValidDate%(obj as Date)
   
    ' check for obvious errors.
    if obj.day < 1 or obj.day > 31 or obj.month < 1 or obj.month > 12 or obj.year < 0 then
        isValidDate% = 0
        exit function
    end if
   
    ' now check specific errors.
    select case obj.month
        case 2:
            if isLeapYear%(obj.year) = 1 then
                if obj.day > 29 then
                    isValidDate% = 0
                    exit function
                end if
            else
                if obj.day > 28 then
                    isValidDate% = 0
                    exit function
                end if
            end if
        case 4, 6, 9, 11:
            if obj.day > 30 then
                isValidDate% = 0
                exit function
            end if
    end select
   
    ' looks okay.
    isValidDate% = 1
   
end function



function getDays&(obj as Date)
   
    dim cumulativeMonthDays(1 to 12) as long
   
    ' ensure we're dealing with a valid date.
    if isValidDate%(obj) = 0 then
        getDays& = -1
        exit function
    end if
   
    ' calculate the days from the year and the day.
    days& = int(obj.year * 365.25) + obj.day
   
    ' now to process the month field...
   
    ' check if we need to account for an extra day in February.
    if isLeapYear%(obj.year) = 1 then
        dayCount& = 1
    else
        dayCount& = 0
    end if
   
    ' set up the month days array.
    cumulativeMonthDays(1) = 0
    dayCount% = dayCount& + 31 ' jan
    cumulativeMonthDays(2) = 31
    dayCount& = dayCount& + 28 ' feb
    cumulativeMonthDays(3) = dayCount&
    dayCount& = dayCount& + 31 ' mar
    cumulativeMonthDays(4) = dayCount&
    dayCount& = dayCount& + 30 ' apr
    cumulativeMonthDays(5) = dayCount&
    dayCount& = dayCount& + 31 ' may
    cumulativeMonthDays(6) = dayCount&
    dayCount& = dayCount& + 30 ' jun
    cumulativeMonthDays(7) = dayCount&
    dayCount& = dayCount& + 31 ' jul
    cumulativeMonthDays(Cool = dayCount&
    dayCount& = dayCount& + 31 ' aug
    cumulativeMonthDays(9) = dayCount&
    dayCount& = dayCount& + 30 ' sep
    cumulativeMonthDays(10) = dayCount&
    dayCount& = dayCount& + 31 ' oct
    cumulativeMonthDays(11) = dayCount&
    dayCount& = dayCount& + 30 ' nov
    cumulativeMonthDays(12) = dayCount&
   
    ' now add the month days on to the day total.
    days& = days& + cumulativeMonthDays(obj.month)
   
    ' set the return value.
    getDays& = days&
   
end function

function isLeapYear%(year as integer)
    modFour% = year and 3
    modOneHundred% = year mod 100
    modFourHundred% = year mod 400
   
    if modFour% = 0 then
        if (modOneHundred% = 0) and (modFourHundred% <> 0) then
            isLeapYear% = 0
            exit function
        end if
       
        isLeapYear% = 1
        exit function
    end if
   
    isLeapYear% = 0
    exit function
   
end function
[/syntax]
Logged

img]http://www.cdsoft.co.uk/misc/shiftlynx.png[/img]
Moneo
Na_th_an
*****
Posts: 1971


« Reply #20 on: June 10, 2005, 11:07:23 PM »

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.
*****
Logged
Moneo
Na_th_an
*****
Posts: 1971


« Reply #21 on: June 10, 2005, 11:11:33 PM »

ShiftLynx,

Your solution looks quite complicate, but nevertheless I'll give it a shot as soon as I finish writing the test program.
*****
Logged
Deleter
Na_th_an
*****
Posts: 1292



WWW
« Reply #22 on: June 11, 2005, 12:55:37 AM »

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.
Logged

Neo
Na_th_an
*****
Posts: 2150



« Reply #23 on: June 11, 2005, 06:25:23 AM »

Hello Moneo,

Quote from: "Moneo"
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 from: "Moneo"
* 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 from: "Moneo"
* 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.

Smiley 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).
Logged
Moneo
Na_th_an
*****
Posts: 1971


« Reply #24 on: June 11, 2005, 02:26:29 PM »

(see next edited post.................)
Logged
Moneo
Na_th_an
*****
Posts: 1971


« Reply #25 on: June 11, 2005, 02:51:23 PM »

Quote from: "Moneo"
Quote from: "Neo"
...
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.
*****
Logged
Moneo
Na_th_an
*****
Posts: 1971


« Reply #26 on: June 11, 2005, 04:21:12 PM »

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.
*****
Logged
Moneo
Na_th_an
*****
Posts: 1971


« Reply #27 on: June 11, 2005, 04:51:04 PM »

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.
*****
Logged
Moneo
Na_th_an
*****
Posts: 1971


« Reply #28 on: June 11, 2005, 09:33:17 PM »

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.
*****
Logged
Deleter
Na_th_an
*****
Posts: 1292



WWW
« Reply #29 on: June 12, 2005, 10:03:22 PM »

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
Logged

Pages: 1 [2] 3
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!