[Python-Dev] Issue5434: datetime.monthdelta

Steven D'Aprano steve at pearwood.info
Fri Apr 17 04:29:11 CEST 2009

On Fri, 17 Apr 2009 07:41:19 am Jess Austin wrote:

> Others have suggested raising an exception when a month calculation
> lands on an invalid date.  Python already has that; it's spelled like
> this:
> >>> dt = date(2008, 1, 31)
> >>> dt.replace(month=dt.month + 1)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ValueError: day is out of range for month
> What other behavior options besides "last-valid-day-of-the-month"
> would you like to see?

Adding one month to 31st January could mean:

1: raise an exception
2: return 28th February (last day of February)
3: return 3rd April (1 month = 31 days)
4: return 2nd April (1 month = 30 days)
5: return 28th February (1 month = 4 weeks = 28 days)
6: next business day after any of the above dates

I don't really expect Python to support scenario 6, as that would 
require knowledge of local public holidays and conventions for week 
ends and working days.

Open Office spreadsheet includes the following relevant functions:

EDATE(start date; months)
returns the serial number of the date that is a specified number of 
months before or after the start date.

EOMONTH(start date; months)
returns the serial number of the last day of the month that comes a 
certain number of months before or after the start date.

MONTHS(start date; end date; type)
calculate the difference in months between start and end date, possible 
values for type include 0 (interval) and 1 (in calendar months).

Rather than a series of almost-identical functions catering for people 
who want 28 day months and 31 day months, I propose a keyword argument 
days_in_month which specifies the number of days in a month. Any 
positive integer should be accepted, but of course only 28, 30 and 31 
will be meaningful for the common English meaning of the word "month". 
0 or None (the default) should trigger "last day of the month" 
behaviour (scenario 2 above).

That will (I think) simplify both documentation and implementation. 
Adding 1 month to a day will be defined as adding days_in_month days 
(if given), and if not given, adding 31 days but truncating the result 
to the last day of the next month.


Steven D'Aprano

More information about the Python-Dev mailing list