Hi Siva, here is code-sample capable of calculating "age" = duration from "birth date" to "query date".
Code segments
- FUNCTION of_dayInPriorMonth -- helper to the next function - treats month for its days.
EXAMPLE: of_dayInPriorMonth ( 2016, 03, 05 ) returns ( 2016, 02, 34 )
- FUNCTION of_Calculate_AGE -- Returns as REF parameters age as years/months/days.
- FUNCTION of_TEST -- Example of calling code. (1) and (2) are functions on n_age_calculator.
REVISION #2
FIX #1: "birth" date before "query" date gave undesired result. ==> Fixed by "intro" block in of_Calculate_Age to handle negative age.
FIX #2: Prefix function calls by "this." ==> Avoid mix-up when someone adds same named global functions.
NOTE: REF prefix highlights every pass-by-REF argument!
(Compiler ignores REF and therefore allows it in front of any argument)
// FUNC of_dayInPriorMonth(REF al_day, REF al_month, REF al_year)
// Converts <day, month, year> into <day+N, month2, year2>
// Where "N" represents number of days in <month2, year2>
// Having <month2, year2> = month before <month, year>
long daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
long moreDays
al_month --
if al_month = 0 then
al_year --; al_month = 12
end if
moreDays = daysInMonth[al_month]
// Adjust for Leap in February only
if al_month = 2 then
choose case true
case Mod(al_year, 400) = 0; moreDays ++
case Mod(al_year, 100) = 0; // Not leap
case Mod(al_year, 4) = 0; moreDays ++
case else; // Not leap
end choose
end if
al_day += moreDays
// FUNCTION of_Calculate_Age( date ad_birth, date ad_query, ...
// ... REF al_ageYears, REF al_ageMonths, REF al_ageDays)
// Ensure correct handling of "birth after query"
if ad_birth > ad_query then
// Negative age => Negate "reverse" age
this.of_Calculate_Age(ad_query, ad_birth, REF al_ageYears, REF al_ageMonths, REF al_ageDays)
al_ageYears *= -1
al_ageMonths *= -1
al_ageDays *= -1
return // DONE
end if
long birthDay, birthMonth, birthYear
long queryDay, queryMonth, queryYear
birthYear = Year(ad_birth); queryYear = Year(ad_query)
birthMonth = Month(ad_birth); queryMonth = Month(ad_query)
birthDay = Day(ad_birth); queryDay = Day(ad_query)
do while birthDay > queryDay
// Convert "incomplete month" into days
this.of_dayInPriorMonth(REF queryYear, REF queryMonth, REF queryDay)
loop
// Convert "incomplete year" into months
if birthMonth > queryMonth then
queryYear --; queryMonth += 12
end if
al_ageYears = queryYear - birthYear
al_ageMonths = queryMonth - birthMonth
al_ageDays = queryDay - birthDay
// FUNCTION of_TEST( )
long days, months, years
date birthDate = Date(1219, 06, 15) // The Danish national flag's birthdate
date queryDate = Date(2020, 01, 02)
n_age_calculator lnv_age
lnv_age = create n_age_calculator
lnv_age.of_Calculate_Age(birthDate, queryDate, REF years, REF months, REF days)
string ls_title, ls_text
ls_title = string(birthDate,"yyyy.mm.dd") + " - " + string(queryDate, "yyyy.mm.dd")
ls_text = string(DaysAfter(birthDate, queryDate)) + " Days~r~n"
ls_text += string(years) + " years, " + string(months) + " months, " + string(days) + " days."
MessageBox(ls_title, ls_text)
TIPS:
- Use LONG to avoid arithmetic overflow (max "int" = approx. 90 years).
- Documented valid year range in PowerScript is 1000 - 3000.
- It seems to me dates calculate correctly in rang 0001 - 9999.
- The only chance of the loop running more than once is when birthdate is January, 30th -31st and query date is March, 1st - 2nd.
HTH /Michael