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()