> >Local LdMybDay,LdDate >LdMybDay=thisform.txtbday.value >lddate=date() >? age(m.ldmybday,m.lddate) > >*------------------------------------------------------- >* Function...: Age() >* >* Description: Calculates age in years, months, and days >* >* Returns....: Character >* >* Parameters.: tdBirthDay - birth date (required) >* tdToday - "today's" date (optional, defaults to DATE()) >* >* Notes......: This routine returns the calculated age as a nine-character >* string of the form "YYY.MM.DD" where "YYY" is the years, >* "MM" is the months, and "DD" is the days. For example, >* 35 years, 6 months, 15 days old comes back as " 35. 6.15" >* (with embedded spaces as shown, to make parsing easier). >* >* Use VFP's string funtions to parse the result. Use with VAL() >* get numeric results. For example: >* lcAge = AGE( {^1940/10/09}) ** >* lnYears = VAL( LEFT( lcAge, 3)) >* lnMonths = VAL( SUBSTR( lcAge, 5, 2)) >* lnDays = VAL( RIGHT( lcAge, 2)) >* >* To get a return value in one step, combine into one statement. >* For example: >* lnYears = LEFT( AGE( {^1940/10/09}, 3) >* >* The routine returns the empty string if any errors are >* are detected, such as an invalid or missing birthdate, or >* a birthdate greater than "today". >* >* ** For bonus points, what is significant about Oct. 9, 1940? >* >* Limitations: This routine uses FoxPro's GOMONTH() function which works >* for dates in the range 1-Jan-1753 through 31-Dec-9999. >* This routine therefore returns the empty string if it >* is passed a date earlier than 1-Jan-1753. >* >* Author.....: Rick Borup, Information Technology Associates >* http://www.prairienet.org/ita >* >* Warranty...: None. Distributed "AS IS". Check your own results. >* >FUNCTION Age(tdBirthday, tdToday) >#DEFINE EMPTY_STRING "" >* Check parameter(s) and return the empty string if there are any errors. >IF pcount()= 0 && If we didn't get a date, > RETURN EMPTY_STRING && return empty string. >ENDIF >IF TYPE("tdBirthday") != "D" && If parameter is not a date > RETURN EMPTY_STRING && return empty string. >ENDIF >IF EMPTY(tdBirthday) && If it's a bad date > RETURN EMPTY_STRING && return empty string. >ENDIF >IF PARAMETERS() = 1 && If we only got one date, > tdToday = DATE() && then use DATE() for "today". >ENDIF >IF tdBirthday > tdToday && If birthday > today, > RETURN EMPTY_STRING && return empty string. >ENDIF >IF tdBirthday < {^1753/01/01} OR tdToday < {^1753/01/01} && If date < 1-Jan-1753 > RETURN EMPTY_STRING && return empty string. >ENDIF > >* Declare and initialize local memvars. >LOCAL lcAge, ldDate, lnNbrMos, lnYears, lnMonths, lnDays >lcAge = "" && Initialize to empty string. >ldDate = tdBirthday && A work field to increment the date. >STORE 0 TO lnNbrMos, lnYears, lnMonths, lnDays > >* Count months from birthday until today >DO WHILE ldDate < tdToday > ldDate = GOMONTH(ldDate,1) && Add a month to the working date. > DO CASE > CASE ldDate <= tdToday && If less than or equal to today, > lnNbrMos = lnNbrMos + 1 && then increment the counter. > CASE ldDate > tdToday && If we went past today's date, > ldDate = GOMONTH(ldDate, -1) && back up one month > EXIT && and exit the do loop. > ENDCASE > IF lnNbrMos > (999*12) + 11 && Stop a runaway at 999 years, 11 mos. > RETURN EMPTY_STRING && and return empty string so we know it's bad. > ENDIF >ENDDO > >* Calculate the numeric values for the age (years, months, days). >lnYears = INT( lnNbrMos / 12) >lnMonths = lnNbrMos - ( lnYears * 12) >IF ldDate < tdToday && If there are any remaining days, > lnDays = tdToday - ldDate && then calculate how many. >ENDIF > >* Create the return string. >lcAge = STR( lnYears,3) + "." + STR( lnMonths,2) + "." + STR( lnDays,2) > >RETURN lcAge >ENDFUNC && Age() > >