使用Python在给定日期(舍入后一天)添加一个月

scl*_*cls 9 python calendar timedelta pandas python-dateutil

我想在给定日期添加一个月

import datetime
dt = datetime.datetime(year=2014, month=5, day=2)
Run Code Online (Sandbox Code Playgroud)

所以我应该得到

datetime.datetime(year=2014, month=6, day=2)
Run Code Online (Sandbox Code Playgroud)

但随着

dt = datetime.datetime(year=2015, month=1, day=31)
Run Code Online (Sandbox Code Playgroud)

我应该得到

datetime.datetime(year=2015, month=3, day=1)
Run Code Online (Sandbox Code Playgroud)

因为没有2015-02-31(而且我希望我的结果在一天之后回合)

有些月份有31天,有些月份有30天,有些是29天,有些是28天!

所以添加一个datetime.timedelta可能不是一个好的做法(因为我们不知道要添加的天数)

我注意到熊猫有一个有趣的概念 DateOffset

http://pandas.pydata.org/pandas-docs/stable/timeseries.html#dateoffset-objects

但我没有找到Month偏移,只是MonthBeginMonthEnd

我也看到这篇文章 如何使用datetime Python模块计算当前日期六个月的日期?

所以我试过dateutil.relativedelta但是

from dateutil.relativedelta import relativedelta
datetime.datetime(year=2015, month=1, day=31)+relativedelta(months=1)
Run Code Online (Sandbox Code Playgroud)

回报

datetime.datetime(2015, 2, 28, 0, 0)
Run Code Online (Sandbox Code Playgroud)

所以结果在前一天得到了结果.

是否有(干净)的方式来圆天之后

编辑:我给了一个例子,一个月要添加,但我也希望能够添加例如:2年零6个月(使用一个relativedelta(years=2, months=6))

Ffi*_*ydd 4

您可以使用dateutil.relativedelta.relativedelta并手动检查该datetime.day属性,如果原始日期大于新日期,则添加一天。

下面的函数接受一个datetime对象和relativedelta对象。请注意,下面的代码仅适用于数年和数月,我不相信如果您使用低于该值的任何内容(天、小时等),它就不会起作用。您可以轻松地修改此函数以将yearsmonths作为参数,然后在relativedelta函数内部构造函数本身。

from datetime import datetime
from dateutil.relativedelta import relativedelta

def add_time(d, rd):
    day = relativedelta(days=+1)

    out = d + rd
    if d.day > out.day:
        out = out + day

    return out    

# Check that it "rolls over"
print(add_time(datetime(year=2015, month=1, day=29), relativedelta(years=+4, months=+1))) # 2019-03-01 00:00:00
print(add_time(datetime(year=2015, month=3, day=31), relativedelta(years=+0, months=+2))) # 2015-05-01 00:00:00

# Check that it handles "normal" scenarios
print(add_time(datetime(year=2015, month=6, day=19), relativedelta(months=+1))) # 2015-07-19 00:00:00
print(add_time(datetime(year=2015, month=6, day=30), relativedelta(years=+2, months=+1))) # 2017-07-30 00:00:00

# Check across years
print(add_time(datetime(year=2015, month=12, day=25), relativedelta(months=+1))) # 2016-01-25 00:00:00

# Check leap years
print(add_time(datetime(year=2016, month=1, day=29), relativedelta(years=+4, months=+1))) # 2020-02-29 00:00:00
Run Code Online (Sandbox Code Playgroud)