Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: How to...? Convert Date of Birth to Age

From: lmecir:mbox:vol:cz at: 24-Oct-2002 20:41

Hi Joel, ----- Original Message ----- From: "Joel Neely"
> substitue FWD-TOP for DATEDELTA in the snippet below. > > >> age 29/2/2004 28/2/2005 > > == [0 11 28] > > >> datedelta 29/2/2004 28/2/2005 > > == [0 11 30] > > > > >> age 29/2/2004 1/3/2005 > > == [1 0 1] > > >> datedelta 29/2/2004 1/3/2005 > > == [1 0 0] > > > > Which results are correct? > > > The issue (which I didn't think through with sufficient precision > in the earlier discussion) is that we tend to expect all of these > statements to be equivalent: > > last - first = difference > last - difference = first > first + difference = last > > when, in fact, they are not equivalent for date "arithmetic".
Exactly! That is why we must answer the question (Which results are correct?) for our intented application.
> To > illustrate, consider the number of months/days between the dates > 27-Jan-2004 and 03-Mar-2004. Working forward, we observe that: > > 27-Jan-2002 -> 27-Feb-2002 = 1 months 0 days > 27-Feb-2002 -> 03-Mar-2002 = 0 months 4 days > -------------------------------------------- > 27-Jan-2002 -> 03-Mar-2002 = 1 months 4 days > > but working backward, we find that: > > 03-Mar-2002 <- 03-Feb-2002 = 1 months 0 days > 03-Feb-2002 <- 27-Jan-2002 = 0 months 7 days > -------------------------------------------- > 03-Mar-2002 <- 27-Jan-2002 = 1 months 7 days > > and this difference resembles the difference between: > > >> fwd-top 27-jan-2002 03-mar-2002 == [0 1 4] > >> age 27-jan-2002 03-mar-2002 == [0 1 7] > I've concluded that there are two reasons for favoring the > behavior of FWD-TOP over AGE as follows: > > Minor reason: We think of time as moving forward, rather than > backward, so if we must choose, let's use the > direction that matches our experience.
Good point! But what if we have got the origin? (E.g. the date of the birth). Then we should use the counting direction pointing towards the other date regardless of the fact whether we are counting forward. (see the monotonicity discussion below)
> Major reason: Monotonicity. For two dates A and B, where A < B, > we would expect the difference between A and B > (in whatever representation) to increase as B increases. This > behavior is exhibited by FWD-TOP,
it isn't ;-) a: 8/2/2004 b: 1/2/2004 fwd-top a b ; == [0 0 7] ; while b: 9/2/2004 fwd-top a b ; == [0 0 1] Here is another candidate function: new-age: function [birth [date!] date [date!]] [ years months days new ] [ days: date/day - birth/day either date < birth [ if positive? days [ new: to date! reduce [birth/day date/month + 1 date/year] if new/day <> birth/day [ new: to date! reduce [0 date/month + 2 date/year] ] days: date - new date: new ] months: date/month - birth/month years: date/year - birth/year if positive? months [ months: months - 12 years: years + 1 ] ] [ if negative? days [ new: to date! reduce [birth/day date/month - 1 date/year] if new/day <> birth/day [ new: to date! reduce [0 date/month date/year] ] days: date - new date: new ] months: date/month - birth/month years: date/year - birth/year if negative? months [ months: months + 12 years: years - 1 ] ] reduce [years months days] ] foreach [birth date] [ 29/2/2004 28/2/2005 29/2/2004 1/3/2005 8/2/2004 1/2/2004 8/2/2004 29-Mar-2004 8/2/2004 30-Mar-2004 8/2/2004 31-Mar-2004 8/2/2004 1-Apr-2004 8/2/2004 2-Apr-2004 8/2/2004 3-Apr-2004 29/2/2004 29/2/2008 ] [ foreach fnc [fwd-top age new-age] [print [fnc birth date mold do get fnc birth date]] ]