Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
A twist on age calculation.
Message
From
31/12/2004 06:13:56
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
 
To
31/12/2004 05:19:45
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:
00973507
Views:
25
>Morning Sergey,
>
>>Expanding on my previous observation, days applied first, month second and years last. I'm not sure is it better than previous one, though. :)
dob = GOMONTH(GOMONTH(dt-dd, - mm), -yy*12)
>
>Me neither ;-) I decided to test against some random dates and ages as below. It is surprising how seldom that the methods agree, and the variance is far wilder than I expected. Do you see anything wrong with what I am doing?
>
>SET DEFAULT TO c:\vfpstuff\dates
>SET LIBRARY TO age.prg
>
>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
>
>ox = NEWOBJECT("agecalculator")
>SCAN
>
>  * dob = GOMONTH(dt-dd, - (yy*12+mm))
>  REPLACE datedata.dobS WITH GOMONTH(datedata.dod - datedata.ndays, ;
>    - (datedata.nyears * 12 + datedata.nmonths))
>
>  * OR
>  * dob = GOMONTH(GOMONTH(dt-dd, - mm), -yy*12)
>*!*	  REPLACE datedata.dobS WITH GOMONTH(GOMONTH(datedata.dod - datedata.ndays, ;
>*!*	    - datedata.nmonths), - (datedata.nyears * 12))
>
>  ox.CalculateAge(datedata.dobs, datedata.dod)
>  REPLACE datedata.ncyears WITH ox.nyears, datedata.ncmonths WITH ox.nmonths, ;
>    datedata.ncdays WITH ox.ndays
>
>ENDSCAN
>
Jim,
When calculating old dates I suggest to keep away from gomonth() as much as possible. It doesn't work if date is before 1752. I suggest to apply year() first to narrow the gap of dates it doesn't work.
ldToday = {^1902/2/5}
lnYears = 33
lnMonths = 6
lnDays = 18
ldBDate = CalcBdate(m.ldToday,m.lnYears,m.lnMonths,m.lnDays)
oAge = CalcAge(m.ldBDate,m.ldToday)
? ldBdate, oAge.Years, oAge.Months, oAge.Days


Procedure CalcBDate
  Lparameters tdTarget,tnYears,tnMonths,tnDays
  Local ldDate,ldBirth
  ldDate = Gomonth(m.tdTarget-m.tnDays,-m.tnMonths)
  ldBirth = Date(Year(m.ldDate)-m.tnYears,Month(m.ldDate),Day(m.ldDate))
  Return Iif(Empty(m.ldBirth),;
   Date(Year(m.ldDate)-m.tnYears,Month(m.ldDate+1),1), m.ldBirth)
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
Endproc
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