pandas 使用 Python 将一个月添加到给定日期(四舍五入的一天之后)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28189003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add one month to a given date (rounded day after) with Python
提问by scls
I'd like to add one month to a given date
我想给给定的日期加上一个月
import datetime
dt = datetime.datetime(year=2014, month=5, day=2)
so I should get
所以我应该得到
datetime.datetime(year=2014, month=6, day=2)
but with
但与
dt = datetime.datetime(year=2015, month=1, day=31)
I should get
我应该得到
datetime.datetime(year=2015, month=3, day=1)
because there is no 2015-02-31 (and I want my result being round one day after)
因为没有 2015-02-31(我希望我的结果在一天之后是圆的)
Some months have 31 days, some other 30, some 29, some 28 !
有的月份有 31 天,有的有 30 天,有的有 29 天,有的有 28 天!
so adding a datetime.timedeltais probably not a good manner of doing (because we don't know the number of days to add)
所以添加 adatetime.timedelta可能不是一个好方法(因为我们不知道要添加的天数)
I noticed that Pandas have an interesting concept of DateOffset
我注意到 Pandas 有一个有趣的概念 DateOffset
http://pandas.pydata.org/pandas-docs/stable/timeseries.html#dateoffset-objects
http://pandas.pydata.org/pandas-docs/stable/timeseries.html#dateoffset-objects
but I didn't find a Monthoffset, just MonthBeginor MonthEnd
但我没有找到Month抵消,只是MonthBegin或MonthEnd
I see also this post How do I calculate the date six months from the current date using the datetime Python module?
我还看到这篇文章 如何使用 datetime Python 模块计算从当前日期算起六个月的日期?
so I tried dateutil.relativedeltabut
所以我尝试dateutil.relativedelta,但
from dateutil.relativedelta import relativedelta
datetime.datetime(year=2015, month=1, day=31)+relativedelta(months=1)
returns
回报
datetime.datetime(2015, 2, 28, 0, 0)
so result was rounded one day before.
所以结果在前一天四舍五入。
Is there a (clean) way to round day after?
有没有(干净的)方式来圆一天后?
edit:
I gave an example with one month to add but I also want to be able to add for example : 2 years and 6 months (using a relativedelta(years=2, months=6))
编辑:我举了一个要添加一个月的示例,但我也希望能够添加例如:2 年零 6 个月(使用relativedelta(years=2, months=6))
采纳答案by Ffisegydd
You can use dateutil.relativedelta.relativedeltaand manually check the datetime.dayattribute, if the original day is greater than the new day, then add a day.
您可以使用dateutil.relativedelta.relativedelta并手动检查该datetime.day属性,如果原始日期大于新日期,则添加一天。
The function below accepts a datetimeobject and relativedeltaobject. Note that the code below only works for years and months, I don't believe it'll work if you use anything below that (days, hours, etc). You could easily modify this function to take yearsand monthsas arguments and then construct the relativedeltainside the function itself.
下面的函数接受一个datetime对象和relativedelta对象。请注意,下面的代码仅适用于数年和数月,如果您使用低于此值的任何内容(天数、小时数等),我认为它不会起作用。您可以轻松地修改此函数以将years和months作为参数,然后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
回答by eumiro
This seems to work. It is quite clean, but not beautiful:
这似乎有效。它很干净,但并不漂亮:
def add_month(now):
try:
then = (now + relativedelta(months=1)).replace(day=now.day)
except ValueError:
then = (now + relativedelta(months=2)).replace(day=1)
return then
for now in [datetime(2015, 1, 20), datetime(2015, 1, 31), datetime(2015, 2, 28)]:
print now, add_month(now)
prints:
印刷:
2015-01-20 00:00:00 2015-02-20 00:00:00
2015-01-31 00:00:00 2015-03-01 00:00:00
2015-02-28 00:00:00 2015-03-28 00:00:00
It adds one month and tries to replace the day with the original day. If it succeeds, it is no special case. If it fails (ValueError), we have to add another month and go to its first day.
它增加了一个月并尝试用原来的日期替换这一天。如果成功,也不是什么特例。如果失败(ValueError),我们必须再添加一个月并转到它的第一天。
回答by aircraft
Use the bellow method:
使用以下方法:
def datetime_offset_by_months(datetime_origin, n=1):
"""
datetime offset by months
:param datetime_origin: the original datetime
:param n: count of months
:return: after offset datetime
"""
# create a shortcut object for one day
one_day = datetime.timedelta(days=1)
# first use div and mod to determine year cycle
q, r = divmod(datetime_origin.month + n, 12)
# create a datetime_offset
# to be the last day of the target month
datetime_offset = datetime.datetime(
datetime_origin.year + q, r + 1, 1) - one_day
'''
if input date is the last day of this month
then the output date should also be the last
day of the target month, although the day
www.iplaypy.com
may be different.
for example:
datetime_origin = 8.31
datetime_offset = 9.30
'''
if datetime_origin.month != (datetime_origin + one_day).month:
return datetime_offset
'''
if datetime_origin day is bigger than last day of
target month, then, use datetime_offset
for example:
datetime_origin = 10.31
datetime_offset = 11.30
'''
if datetime_origin.day >= datetime_offset.day:
return datetime_offset
'''
then, here, we just replace datetime_offset's day
with the same of datetime_origin, that's ok.
'''
return datetime_offset.replace(day= datetime_origin.day)
the usage of it:
它的用法:
import datetime
now_date = datetime.datetime.now()
off_set_datetime = datetime_offset_by_months(now_date, -2)
print(off_set_datetime)
回答by venpa
Quick solution:
快速解决方案:
import datetime
import calendar
dt = datetime.datetime(year=2014, month=5, day=2)
d = calendar.monthrange(dt.year,dt.month+1)[1]
print dt+datetime.timedelta(days=d+1)
Output for the first input (year=2014, month=5, day=2):
第一个输入的输出(year=2014, month=5, day=2):
2014-06-02 00:00:00
Output for the second input (year=2015, month=1, day=31):
第二个输入的输出(year=2015, month=1, day=31):
2015-03-01 00:00:00

