我需要增加一个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一样好的简单的解决方案吗?
不使用日历的解决方案:
def add_month_year(date, years=0, months=0):
year, month = date.year + years, date.month + months + 1
dyear, month = divmod(month - 1, 12)
rdate = datetime.date(year + dyear, month + 1, 1) - datetime.timedelta(1)
return rdate.replace(day = min(rdate.day, date.day))
def month_sub(year, month, sub_month):
result_month = 0
result_year = 0
if month > (sub_month % 12):
result_month = month - (sub_month % 12)
result_year = year - (sub_month / 12)
else:
result_month = 12 - (sub_month % 12) + month
result_year = year - (sub_month / 12 + 1)
return (result_year, result_month)
def month_add(year, month, add_month):
return month_sub(year, month, -add_month)
>>> month_add(2015, 7, 1)
(2015, 8)
>>> month_add(2015, 7, 20)
(2017, 3)
>>> month_add(2015, 7, 12)
(2016, 7)
>>> month_add(2015, 7, 24)
(2017, 7)
>>> month_add(2015, 7, -2)
(2015, 5)
>>> month_add(2015, 7, -12)
(2014, 7)
>>> month_add(2015, 7, -13)
(2014, 6)
这个实现可能对处理账单的人有一定的价值。
如果您正在处理账单,您可能希望得到“下个月相同的日期(如果可能的话)”,而不是“增加一年的1/12”。
让人困惑的是如果你连续做这个,你实际上需要考虑两个值。否则,对于任何超过27日的日期,你将继续失去几天,直到闰年后的27日。
你需要考虑的价值:
您想要添加一个月的值
你开始的那一天
这样当你加一个月的时候,如果你从31号降到了30号,那么下个月有这一天的时候,你就会回到31号。
我是这样做的:
def closest_date_next_month(year, month, day):
month = month + 1
if month == 13:
month = 1
year = year + 1
condition = True
while condition:
try:
return datetime.datetime(year, month, day)
except ValueError:
day = day-1
condition = day > 26
raise Exception('Problem getting date next month')
paid_until = closest_date_next_month(
last_paid_until.year,
last_paid_until.month,
original_purchase_date.day) # The trick is here, I'm using the original date, that I started adding from, not the last one
编辑-根据你的评论,如果下个月的天数更少,就需要四舍五入,下面是一个解决方案:
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和复制小时,分和秒从源到结果。