Как получить тот же день следующего месяца данного дня в Python, используя datetime - PullRequest
42 голосов
/ 12 февраля 2010

я знаю, используя datetime.timedelta, я могу получить дату нескольких дней от данной даты

daysafter = datetime.date.today() + datetime.timedelta(days=5)

но похоже нет datetime.timedelta(month=1)

Ответы [ 9 ]

125 голосов
/ 12 февраля 2010

Использовать dateutil модуль. Имеет Относительные значения времени :

import datetime
from dateutil import relativedelta
nextmonth = datetime.date.today() + relativedelta.relativedelta(months=1)

Beautiful.

30 голосов
/ 12 февраля 2010

Конечно, нет - если сегодня 31 января, что будет "в тот же день следующего месяца" ?! Очевидно, что правильного решения не существует, поскольку 31 февраля не существует, а модуль datetime не играет в "догадку", что думает пользователь, представляющий эту невозможную проблему без правильного решения (ошибочно) является очевидным решением "; -).

Я предлагаю:

try:
  nextmonthdate = x.replace(month=x.month+1)
except ValueError:
  if x.month == 12:
    nextmonthdate = x.replace(year=x.year+1, month=1)
  else:
    # next month is too short to have "same date"
    # pick your own heuristic, or re-raise the exception:
    raise
6 голосов
/ 17 мая 2012
import calendar, datetime

def next_month ( date ):
    """return a date one month in advance of 'date'. 
    If the next month has fewer days then the current date's month, this will return an
    early date in the following month."""
    return date + datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])
3 голосов
/ 03 сентября 2010
from calendar import mdays
from datetime import datetime, timedelta

today = datetime.now()
next_month_of_today = today + timedelta(mdays[today.month])

Я не хочу импортировать dateutil. Попробуйте это. Удачи.

1 голос
/ 21 июня 2019

Вы можете использовать calendar.nextmonth (из Python 3.7 ).

>>> import calendar
>>> calendar.nextmonth(year=2019, month=6)
(2019, 7)
>>> calendar.nextmonth(year=2019, month=12)
(2020, 1)
1 голос
/ 29 июня 2016

Эта работа для меня

import datetime
import calendar


def next_month_date(d):
    _year = d.year+(d.month//12)
    _month =  1 if (d.month//12) else d.month + 1
    next_month_len = calendar.monthrange(_year,_month)[1]
    next_month = d
    if d.day > next_month_len:
        next_month = next_month.replace(day=next_month_len)
    next_month = next_month.replace(year=_year, month=_month)
    return next_month

использование:

d = datetime.datetime.today()
print next_month_date(d)
0 голосов
/ 29 марта 2018

Посмотрев, какой месяц равен 32 дням, вы можете определить, является ли это последним днем ​​месяца и существует ли дата в следующем месяце. Это связано с тем, что хотя бы один из двух месяцев подряд содержит 31 день

from datetime import date, timedelta

def in_a_month(d):
    in_32_days = d + timedelta(32)
    if (in_32_days.month - d.month) % 12 > 1:
        return in_32_days - timedelta(in_32_days.day)
    else:
        return date(in_32_days.year, in_32_days.month, d.day)

Или если вам нужно решение для добавления или удаления произвольного количества месяцев

from datetime import date, timedelta

def last_day_in_month(a_date, months_forward = 0):
    month_index = a_date.year * 12 + a_date.month + months_forward
    y = month_index // 12
    m = (month_index % 12) + 1
    return date(y, m, 1) - timedelta(1)

def add_month(a_date, months = 1):
    is_last_day = a_date == last_day_in_month(a_date)
    last_in_target_month = last_day_in_month(a_date, months)
    if is_last_day or a_date.day > last_in_target_month.day:
        return last_in_target_month
    else:
        return last_in_target_month.replace(day = a_date.day)
0 голосов
/ 09 июля 2014

Вот как я это решил.

from datetime import date
try:
    (year, month) = divmod(date.today().month, 12)
    next_month = date.today().replace(year=date.today().year+year, month=month+1)
except ValueError:
    # This day does not exist in next month

Вы можете пропустить попытку / поймать, если вы хотите только первый день следующего месяца, установив replace(year=date.today().year+year, month=month, day=1). Это всегда будет действительная дата, так как мы обнаружили переполнение месяца с помощью divmod.

0 голосов
/ 03 мая 2014
from datetime import timedelta
try:
    next_month = (x.replace(day=28) + timedelta(days=7)).replace(day=x.day)
except ValueError:  # assuming January 31 should return last day of February.
    next_month = (x + timedelta(days=31)).replace(day=1) - timedelta(days=1)
...