4

I am trying to get the date delta by subtracting today's date from the nth day of the next month.

delta = nth_of_next_month - todays_date
print delta.days

How do you get the date object for the 1st (or 2nd, 3rd.. nth) day of the next month. I tried taking the month number from the date object and increasing it by 1. Which is obviously a dumb idea because 12 + 1 = 13. I also tried adding one month to today and tried to get to the first of the month. I am sure that there is a much more efficient way of doing this.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Johnston
  • 20,196
  • 18
  • 72
  • 121
  • I'd imagine all you need to do is increment the month property of the date object. This previous answer shows how since the month property is not writable http://stackoverflow.com/a/4131114/333082 – cecilphillip Jan 15 '14 at 18:45
  • Why do you care about "more efficient" here? The obvious and simple implementation in sunshine's answer takes only 0.46us to do all that "expensive" work, compared to 1.64us to call `now()`. So I highly doubt it will be a bottleneck in your code. The simplest implementation—one that you understand, and can debug easily—is better than the fastest one, unless it's affecting your total runtime. – abarnert Jan 15 '14 at 19:00
  • @abarnert exactly what I meant... Efficient to me. Not computing power. – Johnston Jan 15 '14 at 19:05

5 Answers5

7

The dateutil library is useful for this:

from dateutil.relativedelta import relativedelta
from datetime import datetime

# Where day is the day you want in the following month
dt = datetime.now() + relativedelta(months=1, day=20)
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • 1
    http://labix.org/python-dateutil#head-6a1472b7c74e5b8bab7784f11214250d34e09aa5 explains what is going on with relativedelta – Peter Lustig Jan 15 '14 at 18:52
6

This should be straightforward unless I'm missing something in your question:

import datetime

now = datetime.datetime.now()
nth_day = 5
next_month = now.month + 1 if now.month < 12 else 1 # February
year = now.year if now.month < 12 else now.year+1
nth_of_next_month = datetime.datetime(year, next_month, nth_day)
print(nth_of_next_month)

Result:

2014-02-05 00:00:00

Using dateutil as suggested in another answer is a much better idea than this, though.

senshin
  • 10,022
  • 7
  • 46
  • 59
2

Another alternative is to use delorean library:

Delorean is a library that provides easy and convenient datetime conversions in Python.

>>> from delorean import Delorean
>>> d = Delorean()
>>> d.next_month()
Delorean(datetime=2014-02-15 18:51:14.325350+00:00, timezone=UTC)
>>> d.next_month().next_day(2)
Delorean(datetime=2014-02-17 18:51:14.325350+00:00, timezone=UTC)
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
1

My approach to calculating the next month without external libraries:

def nth_day_of_next_month(dt, n):
    return dt.replace(
        year=dt.year + (dt.month // 12),  # +1 for december, +0 otherwise
        month=(dt.month % 12) + 1,        # december becomes january
        day=n)

This works for both datetime.datetime() and datetime.date() objects.

Demo:

>>> import datetime
>>> def nth_day_of_next_month(dt, n):
...     return dt.replace(year=dt.year + (dt.month // 12), month=(dt.month % 12) + 1, day=n)
... 
>>> nth_day_of_next_month(datetime.datetime.now(), 4)
datetime.datetime(2014, 2, 4, 19, 20, 51, 177860)
>>> nth_day_of_next_month(datetime.date.today(), 18)
datetime.date(2014, 2, 18)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

Without using any external library, this can be achived as follows

from datetime import datetime, timedelta

def nth_day_of_next_month(n):
    today = datetime.now()
    next_month_dt = today + timedelta(days=32-today.day)
    return next_month_dt.replace(day=n)
Sunny Nanda
  • 2,362
  • 1
  • 16
  • 10