daydreamer
daydreamer

Reputation: 92019

Python : How to add month to December 2012 and get January 2013?

>>> start_date = date(1983, 11, 23)
>>> start_date.replace(month=start_date.month+1)
datetime.date(1983, 12, 23)

This works until the month is <=11, as soon as I do

>>> start_date = date(1983, 12, 23)
>>> start_date.replace(month=start_date.month+1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: month must be in 1..12

How can I keep adding months which increments the year when new month is added to December?

Upvotes: 7

Views: 12196

Answers (5)

John Gaines Jr.
John Gaines Jr.

Reputation: 11534

You're going to have to decide how you want to deal with the weird cases like Jan 31 + 1 month = Feb 31 (which doesn't exist). But I'd lean towards using timedelta to add to your date as in:

import datetime as dt
dt.datetime.now() + dt.timedelta(days=30)

Where you could choose days based on the size of the current or next month, or some such other value so you don't overflow the next month.

Upvotes: 0

Michael
Michael

Reputation: 7756

If you want to have a more general solution for this problem, e.g. adding days, months and years mixed to one date:

import time, datetime, calendar
def upcount(dt, years=0, months=0, **kwargs):
    if months:
        total_months = dt.month + months
        month_years, months = divmod(total_months, 12)
        if months == 0:
            month_years -= 1
            months = 12
        years += month_years
    else:
        months = dt.month

    years = dt.year + years
    try:
        dt = dt.replace(year=years, month=months)
    except ValueError:
        # 31st march -> 31st april gives this error
        max_day = calendar.monthrange(years, months)[1]
        dt = dt.replace(year=years, month=months, day=max_day)

    if kwargs:
        dt += datetime.timedelta(**kwargs)
    return dt

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599628

The dateutil library is useful for calculations like that:

>>> start_date + relativedelta(months=2)
datetime.date(1984, 1, 23)

Upvotes: 13

Andrew Clark
Andrew Clark

Reputation: 208505

Using datetime.timedelta and calendar.monthrange:

>>> from datetime import date, timedelta
>>> import calendar
>>> start_date = date(1983, 12, 23)
>>> days_in_month = calendar.monthrange(start_date.year, start_date.month)[1]
>>> start_date + timedelta(days=days_in_month)
datetime.date(1984, 1, 23)

Upvotes: 5

Joran Beasley
Joran Beasley

Reputation: 113998

try:
    start_date.replace(month=start_date.month+1)
except ValueError:
    if start_date.month == 12:
         start_date.replace(month=1)
         start_date.replace(year=start_date.year+1)
    else:
         raise

Upvotes: 4

Related Questions