python 加一个月 日期,有没有一种简单的方法可以在Python中将datetime对象增加一个月?...

本文探讨如何在Python中处理日期时间对象,包括如何精确增加一个月,确保日期在跨月时正确映射到下个月的对应日期,如1月31日变为2月28日或31日。作者介绍了使用datetime和relativedelta库的技巧,以及避免常见问题的方法,如闰秒处理和日期边界检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本问题已经有最佳答案,请猛点这里访问。

所以我试图找到一种方法,将日期时间对象增加一个月。然而,根据这个问题,这似乎不是那么简单。

我希望有这样的事情:

import datetime as dt

now = dt.datetime.now()

later = now + dt.timedelta(months=1)

但那不管用。如果可能的话,我也希望能够在下个月的同一天(或者最近的一天)去。例如,设置为1月1日的日期时间对象将增加到2月1日,而设置为2月28日的日期时间对象将增加到3月31日,而不是3月28日。

很明显,2月28日(通常)会映射到3月31日,因为它是一个月的最后一天,因此应该转到下个月的最后一天。否则,这将是一个直接的链接:增量应该转到下个月的同一个编号的日期。

在当前的Python版本中,有没有一种简单的方法可以做到这一点?

您需要更全面地指定所需的行为。为什么2月28日的地图要到3月31日?2月27日的地图应该是什么?3月30日?2月14日怎么样?2月15日?噢,"最近的选择"是什么意思?这并不明显。

@西哈,你需要更具体一点。我相信这样会改变那些不被接受的答案,从而使投票模式多样化。

stackoverflow.com/a/4406260/2632856

@西哈现在清楚了。谢谢。

查看EDOCX1[2]为了给一个日期增加一个特定的时间量,您可以继续使用timedelta来处理简单的事情,即。

use_date = use_date + datetime.timedelta(minutes=+10)

use_date = use_date + datetime.timedelta(hours=+1)

use_date = use_date + datetime.timedelta(days=+1)

use_date = use_date + datetime.timedelta(weeks=+1)

或者你可以开始使用relativedelta。

use_date = use_date+relativedelta(months=+1)

use_date = use_date+relativedelta(years=+1)

下个月最后一天:

use_date = use_date+relativedelta(months=+1)

use_date = use_date+relativedelta(day=31)

现在,这将提供2016年2月29日

下个月倒数第二天:

use_date = use_date+relativedelta(months=+1)

use_date = use_date+relativedelta(day=31)

use_date = use_date+relativedelta(days=-1)

下个月的最后一个星期五:

use_date = use_date+relativedelta(months=+1, day=31, weekday=FR(-1))

下个月的第二个星期二:

new_date = use_date+relativedelta(months=+1, day=1, weekday=TU(2))

这绝不是一份详尽的清单。文档可从以下网址获取:https://dateutil.readthedocs.org/en/latest/

这个怎么样?

def add_one_month(orig_date):

# advance year and month by one month

new_year = orig_date.year

new_month = orig_date.month + 1

# note: in datetime.date, months go from 1 to 12

if new_month > 12:

new_year += 1

new_month -= 12

new_day = orig_date.day

# while day is out of range for month, reduce by one

while True:

try:

new_date = datetime.date(new_year, new_month, new_day)

except ValueError as e:

new_day -= 1

else:

break

return new_date

编辑:

改进版本:

如果给定datetime.datetime对象,则保留时间信息

不使用try/catch,而是使用stdlib中的calendar模块中的calendar.monthrange:

import datetime

import calendar

def add_one_month(orig_date):

# advance year and month by one month

new_year = orig_date.year

new_month = orig_date.month + 1

# note: in datetime.date, months go from 1 to 12

if new_month > 12:

new_year += 1

new_month -= 12

last_day_of_month = calendar.monthrange(new_year, new_month)[1]

new_day = min(orig_date.day, last_day_of_month)

return orig_date.replace(year=new_year, month=new_month, day=new_day)

在热循环中抛出异常不是一个好的实践。

怎么会是热循环?最多循环3次。在给定随机日期的情况下,异常被抛出的次数相对较少,平均每个调用大约有0.016(6/365.25)个异常。如果这成为某个人的性能瓶颈,他们可以根据需要进行优化。

关于性能,我什么也没说,这并不是特例在软件工程中的用途。它们应该是例外情况,而不是通常的业务逻辑。

这不是截断时间信息吗?

好吧,长话短说,滚动你自己的日期代码是不明智的。对于某些类项目来说,这可能已经足够好用了,但是在处理日期时,您确实应该使用一个受支持、测试良好的库。因此,OP问题的答案可能只是"不",但我希望有一个或两个标准库用于这个非常常见的问题(我认为在链接的问题中讨论)。

在闰秒时引发异常。

@Djechlin:嗯,python的datetime一开始甚至不支持闰秒。

@真的吗?我一直认为这类事情很重要。

问题:在当前的Python版本中,有没有一种简单的方法可以做到这一点?

答:在当前的Python版本中,没有简单(直接)的方法可以做到这一点。

参考:请参考docs.python.org/2/library/datetime.html,第8.1.2节。TimeDelta对象。正如我们可以理解的那样,我们不能直接增加月份,因为它不是一个统一的时间单位。

另外:如果您想要第一天->第一天和最后一天->最后一天的映射,您应该在不同的月份分别处理它。

这不是一个有用的答案,因为真的没有理由相信你是对的,而不仅仅是误传。

不一定。他不会问"做那件事的简单方法是什么?"但"有没有简单的方法可以做到这一点?"答案是否定的。也许这个答案会阻止他白白浪费时间,并开始实施一个对他有用的解决方案,从而节省他时间和精力。

需要引文。你不是引文。

查找主要库(dateutil!)这就实现了它,这意味着它不存在于标准库中。引用行业领导者的博客文章。向控制该特性的Python的任何主体显示一个正式请求,或者在python n+1中找到直接支持它的计划。显示与此不兼容的python特性。为唯一有意义的地方显示文档。等。。。。

请看一下:docs.python.org/2/library/datetime.html,第8.1.2节。TimeDelta对象。请考虑OP要求"稍后=现在+dt.timedelta(months=1)"。正如您所看到的,您不能直接增加月份,因为它不是统一的。顺便说一句,有人已经给出了一个完整的答案。

好吧,把这个加到你的答案里,而不是告诉我。

@Djechlin引用了一篇由业内领袖撰写的博客——通过呼吁权威来寻找证据。反克拉克的第一定律,一个公认的知名人士说"不可能"的事情可能是错误的。;

@让我列出的所有东西都很好?太好了,谢谢。还有,一个尼特:证据!=证据。埃里克·利珀特相信C的某些东西是事实的证据。我并不认为这是一个谬论,但对每个人都是如此。

@苔丝·艾克勒·欧奇,继续这个讨论:物理学!=编程语言功能是否不存在。有时很有可能证明某些事情是不可能的。我相信你有足够的才智来做出区分;)

>>> now

datetime.datetime(2016, 1, 28, 18, 26, 12, 980861)

>>> later = now.replace(month=now.month+1)

>>> later

datetime.datetime(2016, 2, 28, 18, 26, 12, 980861)

编辑:失败

y = datetime.date(2016, 1, 31); y.replace(month=2) results in ValueError: day is out of range for month

这不是一个简单的方法,但是你可以使用你自己的功能,如下面的回答。

y = datetime.date(2016, 1, 31); y.replace(month=2)导致ValueError: day is out of range for month。

@塔莱纳,看起来没有简单的答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值