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.