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

d0r*_*ife 30 python datetime

所以我试图找到一种方法将datetime对象增加一个月.然而,根据这个问题,似乎并非如此简单.

我希望有类似的东西:

import datetime as dt

now = dt.datetime.now()
later = now + dt.timedelta(months=1)
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我也希望能够在下个月(如果可能的话)去同一天(或最接近的替代方案).例如,DateTime对象定在1月1日将递增到2月1日,而设定在2月28日期时间对象将递增到3月31日,而不是3月28日或东西.

需要明确的是,2月28日将(通常)映射到3月31日,因为它是该月的最后一天,因此它应该到下个月的最后一天.否则它将是一个直接链接:增量应该在下一个月的日期与相同的编号日.

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

Rol*_*ony 68

检查是否from dateutil.relativedelta import * 为日期添加了特定的时间,您可以继续使用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)
Run Code Online (Sandbox Code Playgroud)

或者你可以开始使用了 relativedelta

use_date = use_date+relativedelta(months=+1)

use_date = use_date+relativedelta(years=+1)
Run Code Online (Sandbox Code Playgroud)

在下个月的最后一天:

use_date = use_date+relativedelta(months=+1)
use_date = use_date+relativedelta(day=31)
Run Code Online (Sandbox Code Playgroud)

现在这将提供29/02/2016

在下个月的倒数第二天:

use_date = use_date+relativedelta(months=+1)
use_date = use_date+relativedelta(day=31)
use_date = use_date+relativedelta(days=-1)
Run Code Online (Sandbox Code Playgroud)

下个月的上个星期五:

use_date = use_date+relativedelta(months=+1, day=31, weekday=FR(-1))
Run Code Online (Sandbox Code Playgroud)

下个月的第二个星期二:

new_date = use_date+relativedelta(months=+1, day=1, weekday=TU(2))
Run Code Online (Sandbox Code Playgroud)

这绝不是可用内容的详尽清单.文档可在此处获取:https://dateutil.readthedocs.org/en/latest/


tal*_*nat 10

注意:这个答案显示了如何只使用来实现这个datetime和calendar标准库(STDLIB)模块-这就是被明确提出的要求。接受的答案显示了如何使用许多专用的非 stdlib 库之一更好地实现这一目标。如果您可以使用非 stdlib 库,请务必对此类日期/时间操作进行操作!

这个怎么样?

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
Run Code Online (Sandbox Code Playgroud)

编辑:

改进版本:

  1. 如果给定 datetime.datetime 对象,则保留时间信息
  2. 不使用 try/catch,而是使用calendar.monthrange来自calendarstdlib 中的模块:
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)
Run Code Online (Sandbox Code Playgroud)

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