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

Is there a simple way to increment a datetime object one month in Python?

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

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

我希望有这样的事情:

1
2
3
4
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版本中,有没有一种简单的方法可以做到这一点?


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

1
2
3
4
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

1
2
3
use_date = use_date+relativedelta(months=+1)

use_date = use_date+relativedelta(years=+1)

下个月最后一天:

1
2
use_date = use_date+relativedelta(months=+1)
use_date = use_date+relativedelta(day=31)

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

下个月倒数第二天:

1
2
3
use_date = use_date+relativedelta(months=+1)
use_date = use_date+relativedelta(day=31)
use_date = use_date+relativedelta(days=-1)

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

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

下个月的第二个星期二:

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

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


这个怎么样?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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)


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

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

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

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


    1
    2
    3
    4
    5
    >>> 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)

    编辑:失败

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

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