[Python-Dev] Issue5434: datetime.monthdelta

Lennart Regebro regebro at gmail.com
Sat Apr 18 18:03:52 CEST 2009

On Thu, Apr 16, 2009 at 08:18, Jess Austin <jess.austin at gmail.com> wrote:
> hi,
> I'm new to python core development, and I've been advised to write to
> python-dev concerning a feature/patch I've placed at
> http://bugs.python.org/issue5434, with Rietveld at
> http://codereview.appspot.com/25079.
> This patch adds a "monthdelta" class and a "monthmod" function to the
> datetime module.  The monthdelta class is much like the existing
> timedelta class, except that it represents months offset from a date,
> rather than an exact period offset from a date.  This allows us to
> easily say, e.g. "3 months from now" without worrying about the number
> of days in the intervening months.
>    >>> date(2008, 1, 30) + monthdelta(1)
>    datetime.date(2008, 2, 29)
>    >>> date(2008, 1, 30) + monthdelta(2)
>    datetime.date(2008, 3, 30)
> The monthmod function, named in (imperfect) analogy to divmod, allows
> us to round-trip by returning the interim between two dates
> represented as a (monthdelta, timedelta) tuple:
>    >>> monthmod(date(2008, 1, 14), date(2009, 4, 2))
>    (datetime.monthdelta(14), datetime.timedelta(19))
> Invariant: dt + monthmod(dt, dt+td)[0] + monthmod(dt, dt+td)[1] == dt + td
> These also work with datetimes!  There are more details in the
> documentation included in the patch.  In addition to the C module
> file, I've updated the datetime CAPI, the documentation, and tests.
> I feel this would be a good addition to core python.  In my work, I've
> often ended up writing annoying one-off "add-a-month" or similar
> functions.  I think since months work differently than most other time
> periods, a new object is justified rather than trying to shoe-horn
> something like this into timedelta.  I also think that the round-trip
> functionality provided by monthmod is important to ensure that
> monthdeltas are "first-class" objects.
> Please let me know what you think of the idea and/or its execution.

There are so many meanings of "one month from now" so I'd rather see a
bunch of methods for monthly manipulations than a monthdelta class.

Tuesday February 3rd 2009 + 1 month = Tuesday March 3rd 2009

Not obvious:
Tuesday March 3rd 2009 + 1 month = Tuesday April 7th 2009 (5 weeks)
Tuesday April 7th 2009 + 1 months = Tuesday May 5th 2009 (4 weeks)

Tuesday March 31st 2009 + 1 month = what? Thursday April 30th 2009? Error?

Just supporting the obvious case is just not enough to be worth the work. Doing
  month = month + 1
  if month > 12:
     month = 1
     year = year +1
  lastday = calendar.monthrange(year, month)[1]
  if day > lastday:
    day = lastday

Isn't really enough work to warrant it's own class IMO, even though
it's a method I also end up doing all the time in every bloody
calendar implementation I've done. :)

And then comes the same question when talking about years.
One year after the 20th of March 2011 may be the 20th of March 2012.
But it could also be 19th of March, as 2012 is a leap year. And a year
later still would then be the 20th of Match 2013 again... Code that
doesn't support ALL the weird-ass variants is really not worth putting
into the standard library, IMO.

I'd recommend you to look at the dateutil.rrule code, maybe there is
something you can use there. Perhaps there is something there that can
be used straight off. Or at least maybe it can be extracted to it's
own extended timedelta library that supports more advanced timedeltas,
including "second to last wednesday" and "first sunday after easter".

Lennart Regebro: Python, Zope, Plone, Grok
+33 661 58 14 64

More information about the Python-Dev mailing list