How to find difference in years between two dates?

John Machin sjmachin at lexicon.net
Thu Jul 27 20:27:24 EDT 2006


thebjorn wrote:
> John Machin wrote:
> > thebjorn wrote:
> [...]
> > > You give a good argument that the concept of a month is fuzzy
> >
> > Sorry,  I can't imagine where you got "fuzzy" from. Perhaps you mean
> > some other word. The concept is capable of being expressed precisely.
>
> and the second to last date in January plus a month is..?

The last day in February, according to me and also according to the
website that you mention later, e.g.
"""
>From date: Thursday, January 30, 1992
Added 1 month
Resulting date: Saturday, February 29, 1992
"""

The precise rule is that if the original day is later than the last day
of the target month, clip it to that last day.


>
> > Even if I had noticed a leap year function in the calendar module, I
> > would probably not have used it. The Python version of the module was
> > just a stopgap while I fiddled with getting a C extension going. The C
> > leap year function doesn't have any of that modulo stuff in it.
>
> I'm sure it doesn't. You might want to look at the assembly your C
> compiler produces for a modulo-power-of-2 operation...

I don't need to. AFAIR just about every compiler I've used (BDS C on a
Z80 is a likely exception) has generated "& mask" (with extra mucking
about if the first operand is signed). Leap year calc involves % 100
and % 400. Factoring out the powers of two leaves 25. Now tell me how
I'm managing that without a modulo operation.

>
> > > I came up with this yesterday which seems sufficient?
> > >
> > >     def yeardiff(a, b):
> > >       y = a.year - b.year
> > >       if (a.month, a.day) < (b.month, b.day): # tuple comparison
> > >           y -= 1
> > >       return y
> >
> > At least it doesn't blow up when b is leapyear-02-29. It just gives the
> > wrong answer when a is nonleapyear-02-28. E.g. it gives 0 years
> > difference  from 1992-02-29 to 1993-02-28 instead of 1.
>
> I believe you're mistaken (but feel free to correct me), my grandmother
> is born on Feb 29 and a quick call to my dad verified that they
> celebrated it the day after the 28th (unless Mar 1 was a Monday ;-).
> http://timeanddate.com/date/duration.html also seem to agree with my
> current understanding, just as a datapoint if nothing else.

hmm ... let's look at more than 1 data point from that website:

easy cases Jan 1993 to Feb 1993:
Jan 10 to Feb  9: 30d (excluding last day)  1m 0d (including last day)
Jan 10 to Feb 10: 1m 0d  (excluding last day)  1m 1d (including last
day)
Jan 10 to Feb 11: 1m 1d  (excluding last day)  1m 2d (including last
day)
looks reasonable, consistent, no anomalies; note how 1m 0d (excluding)
is "predicted" from the right and below.

Now try from Jan 31 1993:
Jan 31 to Feb 27: 27d (ex) 28d (in)
Jan 31 to Feb 28: 28d (ex) 1m 1d (in)
Jan 31 to Mar 01: 1m 1d (ex) 1m 2d (in)
So 1 day short of 1m 1d is not 1m 0 d??? I'd call this unreasonable,
inconsistent, anomalous -- especially when on the same website you do
1993-01-31 plus 1 month, it gives you 1993-02-28 (as I'd expect).




More information about the Python-list mailing list