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

I ran the same test as before, and it works fine now. Congratulations. Big Grin

However, your code for the "maxday" function looks a little shakey, and I suspect it would not work for any dates.
Code:
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
The second if "if month=2 and ...." does not have the test for mod 400. I'm not sure it needs it, but it's worth taking a look at it.

The third if "if (((month=2 and year ..." does not say "and month=2" for the mod 100 test. Again, I'm not sure it needs it, but take a look.


EDIT: Somehow I got the wrong impression from looking at your code 'cause it looks different. However, I just tested it again using birthdays from the year 1 to the year 2501 with a current date of 12/31/2501, and it works fine. Sorry for under-estimating your code. Good job!

BTW, I also ran Neo's version with the same dates, and his runs fine also.
*****
Reply
#32
the parentheses combined with the AND statements make it a bit confusing. The way that works, the second and doesnt need if month=2, because the first parameter entered requres it. And, the second and doesnt need the 400 check, because the third IF does the check for 400, therefore overriding whatever decision the second if makes. logic, what fun Big Grin
[Image: freebasic.png]
Reply
#33
Enough time has been given to ShiftLynx to fix his entry, and for any others to submit solutions. So, this brings this challenge to a close.

The only solutions that worked were those of Deleter and Neo. During the testing phase, they each enhanced their solutions to a point where even the most stringent testing would not make them fail.

I have to acknowledge both their efforts, and see no other way than to consider them both as equal winners of this challenge. Congratulations Deleter and Neo, and thanks for participating in the challenge and sharing your programming know-how with others.


BTW, here's my own solution for the challenge's problem. You will note that 99% of the program is getting and validating the dates. The actual computation of the age turns out to be 2 lines of code.
Code:
DEFINT A-Z

DECLARE FUNCTION   NumStrict    (Z$)
DECLARE FUNCTION   IsLeapYear%  (Z)  

rem Setup days-per-month table.
DIM ZMO(1 TO 12) AS INTEGER
DATA 31,28,31,30,31,30,31,31,30,31,30,31
FOR ZMM=1 TO 12:READ ZMO(ZMM):NEXT

REM ***********************************************************************

cdate$=date$  'Get current system date as mm-dd-yyyy
if left$(time$,2)="00" then cdate$=date$  'make sure date didn't just roll over
rem System date is assumed to be valid.
cyear = val(mid$(cdate$,7,4))
cmmdd$=left$(cdate$,2)+mid$(cdate$,4,2)
cymd$=mid$(cdate$,7,4)+cmmdd$

input "Enter Person's Date of Birth as YYYYMMDD ", birth$
z$=birth$:gosub date.check
if date.ok=0 or birth$>cymd$ then print "Invalid Birth Date=";birth$:system
byear  = val(mid$(birth$,1,4))
bmmdd$ = mid$(birth$,5,4)

rem Compute the person's age in years.
age=cyear-byear
if bmmdd$ > cmmdd$ then age=age-1
print "The person's age today is ";age
system

REM ****************  DATE.CHECK SUBROUTINE  **************************
REM *
REM *** VALIDATE A DATE IN YYYYMMDD FORMAT.
REM *
REM *  INPUT: Z$       = Given date in format YYYYMMDD.
REM *
REM * OUTPUT: DATE.OK = -1 if input date is VALID.   (true)
REM *                    0 if input date is INVALID. (false)                    
REM *
DATE.CHECK:
  DATE.OK = 0      'preset to false
  IF NOT NUMSTRICT(Z$) THEN RETURN
  ZDD=VAL(RIGHT$(Z$,2))                'Set day                
  ZMM=VAL(MID$(Z$,5,2))                'Set month.
  ZYY=VAL(LEFT$(Z$,4))                 'Set year.
  IF ZMM<1 OR ZMM>12 OR ZDD<1 OR ZDD>31 THEN RETURN
  IF ZMO(ZMM)+1*(-(ZMM=2 AND ISLEAPYEAR(ZYY))) < ZDD THEN RETURN
  '   If expression (month=2 and is leapyear) is TRUE which is -1, then
  '   taking the negative of this issues a plus 1. Conversely, FALSE    
  '   always gives a zero. Multiplying the +1 by this result of 1 or 0
  '   will either add 1 or not to the number of days in the month.
  '   The logic wants to add 1 only when it is February and leap year.
  DATE.OK = -1        '-1=valid (true)
RETURN      

END

REM *****   F U N C T I O N S   *****

' ====================== ISLEAPYEAR ==========================
'         Determines if a year is a leap year or not.
' ============================================================
'
FUNCTION IsLeapYear (Z) STATIC

   ' If the year is evenly divisible by 4 and not divisible
   ' by 100, or if the year is evenly divisible by 400, then
   ' it's a leap year:
   IsLeapYear = (Z MOD 4 = 0 AND Z MOD 100 <> 0) OR (Z MOD 400 = 0)
END FUNCTION
' =================================================================

FUNCTION NumStrict (Z$)

REM *
REM *** CHECK FOR STRICTLY NUMERIC (NO NULL, NO NEGATIVE, NO DECIMAL)
REM *

  NumStrict=0         'Init to False

  IF Z$="" THEN EXIT FUNCTION

  FOR X = 1 TO LEN(Z$)
      A=ASC(MID$(Z$,X,1))
      IF A<48 OR A>57 THEN EXIT FUNCTION
  NEXT X

  NumStrict = -1          'True

END FUNCTION
*****
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)