Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
A twist on age calculation.
Message
From
31/12/2004 07:42:10
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
 
To
31/12/2004 07:24:31
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Environment versions
Visual FoxPro:
VFP 8 SP1
OS:
Windows 2000 SP4
Network:
Windows 2000 Server
Database:
Visual FoxPro
Miscellaneous
Thread ID:
00973330
Message ID:
00973511
Views:
32
This message has been marked as a message which has helped to the initial question of the thread.
>Cetin,
>
>My test using your code:
>
>CREATE CURSOR datedata (dod D, dobS D NULL, nyears N(2,0), nmonths N(2,0), ndays N(3,0), ;
>  ncyears N(3,0), ncmonths N(2,0), ncdays N(3,0))
>=RAND(-1)
>FOR i = 1 TO 1000
>  dDOD = DATE() - INT(IIF(i <= 500000, 1000, 10000) * RAND())
>  nyrs = INT(99 * RAND() + 1)
>  nmths = INT(11 * RAND() + 1)
>  ndys = INT(364 * RAND() + 1)
>  INSERT INTO datedata VALUES (dDOD, NULL, nyrs, nmths, ndys, 0, 0, 0)
>ENDFOR
>
>SCAN
>  REPLACE datedata.dobS WITH CalcBdate(datedata.dod, datedata.nyears, datedata.nmonths, datedata.ndays)
>  loage = calcage(datedata.dobS, datedata.dod)
>  REPLACE datedata.ncyears WITH loage.years, datedata.ncmonths WITH loage.months, ;
>    datedata.ncdays WITH loage.days
>ENDSCAN
>BROWSE LAST
>
>PROCEDURE CalcBdate
>  LPARAMETERS tdTarget,tnYears,tnMonths,tnDays
>  LOCAL ldDate
>  ldDate = GOMONTH(m.tdTarget-m.tnDays,-m.tnMonths)
>  RETURN DATE(YEAR(m.ldDate)-m.tnYears,MONTH(m.ldDate),DAY(m.ldDate))
>ENDPROC
>
>PROCEDURE calcage
>  LPARAMETERS tdBirth, tdTarget
>  LOCAL ldTemp, ldBirth, lnDrop, loage, lnSelect
>  lnSelect = SELECT()
>  CREATE CURSOR (SYS(2015)) (years i,months i,days i)
>  SCATTER NAME loage
>  USE IN (ALIAS())
>  SELECT (m.lnSelect)
>  IF m.tdBirth > m.tdTarget
>    ldTemp   = m.tdTarget
>    tdTarget = m.tdBirth
>    tdBirth  = m.ldTemp
>  ENDIF
>  ldBirth = DATE(YEAR(m.tdTarget),MONTH(m.tdBirth),DAY(m.tdBirth))
>  lnDrop = 0
>  IF EMPTY(m.ldBirth) && leap case
>    ldBirth = DATE(YEAR(m.tdTarget),3,1)
>    lnDrop = IIF(MONTH(m.tdTarget)<=2,0,1)
>  ENDIF
>  WITH loage
>    .years = YEAR(m.tdTarget) - YEAR(m.tdBirth) - ;
>      (IIF(m.ldBirth > m.tdTarget,1,0))
>    .months = (MONTH(m.tdTarget) - MONTH(m.tdBirth) + 12 - ;
>      (IIF(DAY(m.tdBirth)>DAY(m.tdTarget),1,0)))%12
>    ldTemp = DATE( YEAR(m.tdBirth) + .years, MONTH(m.tdBirth), DAY(m.tdBirth) )
>    .days = m.tdTarget - GOMONTH(m.ldTemp,.months) - m.lnDrop
>  ENDWITH
>RETURN loage
>
>
>
>
>and I am still seeing wild differences, with maybe 1 in 30 returing the same 'age'. Pretty much the same results I get using Sergey's and Rick's code.
>
>Thanks for the heads up on GOMONTH(). I'm limiting my data to <99 years, so that shouldn't be a problem.

Jim,
Main problem I think in your routine you're using highly randomized values for days that doesn't fit well saying time difference in YMD.
ie: dod is {^2002/07/21}, died 1 year, 8 months, 328 days ago. dobs then {^1999/12/27}
It's also same as saying died 2 years, 6 months, 24 days ago.

ndys = min(INT(31 * RAND() + 1), day(ddod))

should almost get the differences to 0 (still might be as difference saying could be like:
2 years 2 months 31 days vs 2 years 3 months 0 days).
PS: Check my first reply. It was updated for a slight adjustment in CalcBdate.
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform