Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Compute how many years,months,days
Message
From
31/10/2004 23:07:06
 
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Environment versions
Visual FoxPro:
VFP 5
Miscellaneous
Thread ID:
00955191
Message ID:
00956433
Views:
19
Soykan,

I found a bug in my code (that you quoted below) that causes it to return 1, 2, or 3 too many days under some circumstances. This is fixed in the new code available for download here on UT as file#25738. It has also been updated to be a VFP class instead of an older-style function.

-Rick


>Mohammed,
>save below function eg. calc_age.prg and put this command to the form init
>set proc to calc_age.prg
>
>you can calculate age where you want...
>
>
>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()
>
>
Rick Borup, MCSD

recursion (rE-kur'-shun) n.
  see recursion.
Previous
Reply
Map
View

Click here to load this message in the networking platform