我需要增加一个datetime值的月份

next_month = datetime.datetime(mydate.year, mydate.month+1, 1)

当月份为12时,它变成13,并引发错误“month必须在1..12”。(我预计时间会增加)

我想使用timedelta,但它不带month参数。 有一个relativedelta python包,但我不想只为此安装它。 还有一个使用strtotime的解决方案。

time = strtotime(str(mydate));
next_month = date("Y-m-d", strtotime("+1 month", time));

我不想从datetime转换为str再转换为time,再转换为datetime;因此,它仍然是一个图书馆

有人有像使用timedelta一样好的简单的解决方案吗?


当前回答

好的,通过一些调整和使用timedelta,我们开始:

from datetime import datetime, timedelta


def inc_date(origin_date):
    day = origin_date.day
    month = origin_date.month
    year = origin_date.year
    if origin_date.month == 12:
        delta = datetime(year + 1, 1, day) - origin_date
    else:
        delta = datetime(year, month + 1, day) - origin_date
    return origin_date + delta

final_date = inc_date(datetime.today())
print final_date.date()

其他回答

最简单的解决方法是在月底去(我们都知道每个月至少有28天),并增加足够的时间来研究下一个飞蛾:

>>> from datetime import datetime, timedelta
>>> today = datetime.today()
>>> today
datetime.datetime(2014, 4, 30, 11, 47, 27, 811253)
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
datetime.datetime(2014, 5, 30, 11, 47, 27, 811253)

也适用于不同的年份:

>>> dec31
datetime.datetime(2015, 12, 31, 11, 47, 27, 811253)
>>> today = dec31
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)

请记住,不能保证下个月将有相同的日子,例如从1月31日移动到2月31日,它将失败:

>>> today
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: day is out of range for month

因此,如果您需要移动到下个月的第一天,这是一个有效的解决方案,因为您总是知道下个月是第1天(.replace(day=1))。否则,要移动到最后可用的一天,你可能想使用:

>>> today
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
>>> next_month = (today.replace(day=28) + timedelta(days=10))
>>> import calendar
>>> next_month.replace(day=min(today.day, 
                               calendar.monthrange(next_month.year, next_month.month)[1]))
datetime.datetime(2016, 2, 29, 11, 47, 27, 811253)

编辑-根据你的评论,如果下个月的天数更少,就需要四舍五入,下面是一个解决方案:

import datetime
import calendar

def add_months(sourcedate, months):
    month = sourcedate.month - 1 + months
    year = sourcedate.year + month // 12
    month = month % 12 + 1
    day = min(sourcedate.day, calendar.monthrange(year,month)[1])
    return datetime.date(year, month, day)

在使用:

>>> somedate = datetime.date.today()
>>> somedate
datetime.date(2010, 11, 9)
>>> add_months(somedate,1)
datetime.date(2010, 12, 9)
>>> add_months(somedate,23)
datetime.date(2012, 10, 9)
>>> otherdate = datetime.date(2010,10,31)
>>> add_months(otherdate,1)
datetime.date(2010, 11, 30)

另外,如果你不担心小时、分钟和秒,你可以用date而不是datetime。如果你担心小时,分钟和秒,你需要修改我的代码使用datetime和复制小时,分和秒从源到结果。

也许可以使用calendar.monthrange()添加当前月份的天数?

import calendar, datetime

def increment_month(when):
    days = calendar.monthrange(when.year, when.month)[1]
    return when + datetime.timedelta(days=days)

now = datetime.datetime.now()
print 'It is now %s' % now
print 'In a month, it will be %s' % increment_month(now)

与Dave Webb的解决方案的理想相似,但没有所有棘手的模运算:

import datetime, calendar

def increment_month(date):
    # Go to first of this month, and add 32 days to get to the next month
    next_month = date.replace(day=1) + datetime.timedelta(32)
    # Get the day of month that corresponds
    day = min(date.day, calendar.monthrange(next_month.year, next_month.month)[1])
    return next_month.replace(day=day)

这是一种使用dateutil的relativedelta将一个月添加到日期的简单而甜蜜的方法。

from datetime import datetime
from dateutil.relativedelta import relativedelta
    
date_after_month = datetime.today()+ relativedelta(months=1)
print('Today: ',datetime.today().strftime('%d/%m/%Y'))
print('After Month:', date_after_month.strftime('%d/%m/%Y'))
Today:  01/03/2013

After Month: 01/04/2013

一个警告:relativedelta(months=1)和relativedelta(month=1)有不同的含义。通过month=1将把原始日期中的月份替换为1月,而通过months=1将在原始日期上增加一个月。

注意:这将需要python-dateutil模块。如果你在Linux上,你需要在终端上运行这个命令来安装它。

sudo apt-get update && sudo apt-get install python-dateutil

说明:在python中添加月份值