[REBOL] Re: How to...? Convert Date of Birth to Age
From: joel:neely:fedex at: 23-Oct-2002 15:56
Hi, Ladislav,
Read it again, please! ;-)
Ladislav Mecir wrote:
> > 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]
>
For two dates A and B, where A < B ...
===========
In the example you proposed, A is 8-Feb-2004 and B is 1-Feb-2004,
therefore you violated the precondition A < B. I'm afraid the
example you offered simply shows that one can find another date
that is *closer* to 8-Feb-2004 than is 1-Feb-2004.
The reason I stated the condition that way is that the function I
supplied computes the *absolute* difference between two dates; it
tells how far apart two dates are, leaving it up to the caller to
deal with before-versus-after comparisons on the dates themselves.
However, I'm quite happy to state the monotonicity condition in
another way:
Let C be the difference between two dates A and B. If the
larger of A and B is increased, or the smaller of A and B
is decreased, the new difference D should be larger than C.
All that amounts to is a more formal statement of the intent that
if the dates "get further apart" in the ordinary sense of that
phrase, then the computed difference should increase and not
zig-zag back and forth.
> Here is another candidate function:
>
> new-age: function [birth [date!] date [date!]] [
> years months days new
> ] [
...
> ]
>
Which raises the interesting question: what is the date exactly one
year and one month after 29-Jan-2000? ;-)
>> nyy: 2000
== 2000
>> nym: 1
== 1
>> nyd: 29
== 29
>> to-date reduce [nyy nym nyd]
== 29-Jan-2000
>> to-date reduce [nyy + 1 nym + 1 nyd]
== 1-Mar-2001
I believe that FWD-TOP returns triplets that are consistent with the
way REBOL converts blocks to dates.
>> base: 29-jan-2000
== 29-Jan-2000
>> base-blk: reduce [base/year base/month base/day]
== [2000 1 29]
>> target: 01-mar-2001
== 1-Mar-2001
>> incr-blk: fwd-top base target
== [1 1 0]
>> target = to-date for i 1 3 1 [append [] base-blk/:i +
incr-blk/:i]
== true
> Exactly! That is why we must answer the question (Which results
> are correct?) for our intented application.
>
We're *totally* in agreement on that point. The question, "How far
apart are two given dates, with the result represented in years,
months, and days?" is underspecified. However, I'm playing with the
related question, "Given an underspecified problem, are there some
properties that would make some solutions preferable to others?"
As an aside, there's a psychological component: if someone asked,
How many years, months, and days until 31-dec-2004?
we might
imagine that there's something significant about the number 31,
and respond that 30-nov-2002 is 2 years and 1 month exactly prior
to the target date, because the jump from one last-day-of-month
to another last-day-of-month would seem naturally to be some
number of whole months... However, the more such things enter into
our designs (at least unsolicited!) the more we are creating very
brittle objects that will undoubtedly surprise us at some point, or
exhibit some other inconsistency with a different use.
Just more evidence that programming is simple until we have to deal
with the "real world"! ;-)
-jn-
--
----------------------------------------------------------------------
Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446