Hey -

why not use the follow approximation:

birthdate: day-month-year
today: now/date

daysold: today - birthdate

yearsold: to-integer daysold / 365.2425

Since to-integer always rounds down, you end up with an a relatively
accurate age.  REBOL seems to be pretty good about date arithmetic
(accounting for leap years).  I haven't tested the above that extensively,
but it's come up roses for friends and family.

- Porter


----- Original Message -----
From: "Joel Neely" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Wednesday, July 03, 2002 9:21 AM
Subject: [REBOL] Re: How to...? Convert Date of Birth to Age


> Hi, Andrew,
>
> Andrew Martin wrote:
> >
> > Using Rebol (of course!), how would I convert a date of birth to
> > an age in years, months and days?
> >
>
> First a couple of observations:
>
> -  Date arithmetic is non-trivial; tricks with 365.25 (or 365.2425,
>    to be more precise ;-) days are fragile in the presence of leap
>    years.
> -  Keeping up with lots of boilerplate (e.g. days per month) offers
>    many opportunities for typos with subtle bugs.
> -  As with sorting, one can do things simply (trading away speed)
>    or highly tuned (trading away simplicity and clarity).
>
> All of that said, here's a "bubble-sort-style" solution.  It's not
> a speed winner (and isn't suitable for large problems), but should
> be obvious and clear enough that you can type it from memory any
> time you need such a calculation.  First, a version with comments
> explaining the strategy:
>
> 8<----------------------------------------------------------------
>
> datedelta: func [
>     bdate [date!] edate [date!]
>     /local result temp adjust
> ][
> ;
> ;   ensure proper order
> ;
>     if bdate > edate [temp: bdate bdate: edate edate: temp]
> ;
> ;   result = difference between bdate and temp (initially zero)
> ;
>     temp:   reduce [bdate/year bdate/month bdate/day]
>     result: copy [0 0 0]
> ;
> ;   function to modify a date component [y=1 m=2 d=3]
> ;   in both result and temp by the same adjustment amount
> ;
>     adjust: func [pos [integer!] delta [integer!]] [
>         poke result pos result/:pos + delta
>         poke temp   pos temp/:pos   + delta
>     ]
> ;
> ;   tally difference in years, then months, then days
> ;
>     foreach datepart [1 2 3] [
> ;
> ;   adjust up until overshoot
> ;
>         while [edate > to-date temp] [ adjust datepart 1 ]
> ;
> ;   correct any overshoot
> ;
>         while [edate < to-date temp] [ adjust datepart -1 ]
>
>     ]
> ;
> ;   result = difference between bdate and temp
> ;   temp   = edate
> ;   ergo result is final answer
> ;
>     result
> ]
>
> 8<----------------------------------------------------------------
>
> ... then a version without comments to help remember just the code:
>
> 8<----------------------------------------------------------------
>
> datedelta: func [
>     bdate [date!] edate [date!]
>     /local result temp adjust
> ][
>     if bdate > edate [temp: bdate  bdate: edate  edate: temp]
>     temp:   reduce [bdate/year bdate/month bdate/day]
>     result: copy [0 0 0]
>     adjust: func [pos [integer!] delta [integer!]] [
>         poke result pos result/:pos + delta
>         poke temp   pos temp/:pos   + delta
>     ]
>     foreach datepart [1 2 3] [
>         while [edate > to-date temp] [adjust datepart  1]
>         while [edate < to-date temp] [adjust datepart -1]
>
>     ]
>     result
> ]
>
> 8<----------------------------------------------------------------
>
> HTH!
>
> -jn-
>
> --
> ; Joel Neely                             joeldotneelyatfedexdotcom
> REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
> do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
> | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
> --
> To unsubscribe from this list, please send an email to
> [EMAIL PROTECTED] with "unsubscribe" in the
> subject, without the quotes.
>
>

-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to