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: joel::neely::fedex::com at: 22-Oct-2002 18:46

Hi, Ladislav, I'm long overdue to reply to this, but have had occasion to revisit the "difference of dates" problem. For various obscure reasons, substitue FWD-TOP for DATEDELTA in the snippet below. Ladislav Mecir wrote:
> Hi, > > >> 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". 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]
So, as you asked, which is "correct"? 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. 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, but not by AGE, as shown in the following example:
>> for target 29-mar-2004 03-apr-2004 1 [
[ print [target tab mold fwd-top 08-feb-2004 target] [ ] 29-Mar-2004 [0 1 21] 30-Mar-2004 [0 1 22] 31-Mar-2004 [0 1 23] 1-Apr-2004 [0 1 24] 2-Apr-2004 [0 1 25] 3-Apr-2004 [0 1 26]
>> for target 29-mar-2004 03-apr-2004 1 [
[ print [target tab mold age 08-feb-2004 target] [ ] 29-Mar-2004 [0 1 21] 30-Mar-2004 [0 1 22] 31-Mar-2004 [0 1 23] 1-Apr-2004 [0 1 22] 2-Apr-2004 [0 1 23] 3-Apr-2004 [0 1 24] I have trouble with the idea that a baby born on 08-feb-2004 will be the same age (in months/days) on 1-apr-2004 as (s)he was two days earlier. This is (to me, at least) an interesting demonstration of the fact that the "real world" of everyday activity, and the "ideal world" of computing, do not always correspond as nicely as we programmers would like to think they do! ;-) -jn- PS: To save anyone the trouble of digging through dusty email archives, the relevant function definitions appear below: fwd-top: func [ lo [date!] hi [date!] /local y m d i j k ][ if hi < lo [k: lo lo: hi hi: k] y: lo/year m: lo/month d: lo/day i: j: k: 0 while [hi > to-date reduce [y m d]] [y: y + 1 i: i + 1] while [hi < to-date reduce [y m d]] [y: y - 1 i: i - 1] while [hi > to-date reduce [y m d]] [m: m + 1 j: j + 1] while [hi < to-date reduce [y m d]] [m: m - 1 j: j - 1] while [hi > to-date reduce [y m d]] [d: d + 1 k: k + 1] while [hi < to-date reduce [y m d]] [d: d - 1 k: k - 1] reduce [i j k] ] age: function [birth [date!] date [date!]] [years months days new] [ if date < birth [ return head insert age date birth '- ] days: date/day - birth/day if negative? days [ months: birth/month + 1 years: birth/year if months > 12 [ months: 1 years: years + 1 ] new: to date! reduce [1 months years] days: new - birth + date/day - 1 birth: new ] months: date/month - birth/month years: date/year - birth/year if negative? months [ months: months + 12 years: years - 1 ] reduce [years months days] ] -- ---------------------------------------------------------------------- Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446