我正在使用datetime Python模块。我希望从当前日期计算6个月的日期。有人能帮我一下吗?

我想从当前日期生成一个6个月后的日期的原因是为了生成一个回顾日期。如果用户在系统中输入数据,系统将有从输入数据之日起6个月的审查日期。


当前回答

我有一个更好的办法来解决“2月31日”的问题:

def add_months(start_date, months):
    import calendar

    year = start_date.year + (months / 12)
    month = start_date.month + (months % 12)
    day = start_date.day

    if month > 12:
        month = month % 12
        year = year + 1

    days_next = calendar.monthrange(year, month)[1]
    if day > days_next:
        day = days_next

    return start_date.replace(year, month, day)

我认为它也适用于负数(减去月份),但我还没有对此进行过多测试。

其他回答

我知道这个问题已经有很多答案,但是使用collections.deque和rotate()方法,可以创建一个函数,该函数接受一个datetime对象作为输入,然后输出一个比当前对象晚一个“业务月”的新datetime对象。如果该月的某一天在下个月不存在,则减去1,直到它到达该月的有效日期,然后返回该对象。

import collections
import datetime

def next_month(dt: datetime.datetime):
    month_list = list(range(1, 12 + 1))
    months = collections.deque(month_list)
    while True:
        this_month = list(months)[0]
        if dt.month == this_month:
            break
        months.rotate(-1)
    months.rotate(-1)
    month_plus = list(months)[0]
    for i in range(4):
        try:
            return dt.replace(month=month_plus, day=dt.day - i)
        except ValueError:
            continue

使用itertools.cycle也可以得到相同的结果。

import datetime
import itertools

def next_month(dt: datetime.datetime):
    month_list = list(range(1, 12 + 1))
    month = itertools.cycle(month_list)
    while True:
        if next(month) == dt.month:
            break
    month_plus = next(month)
    for i in range(4):
        try:
            return dt.replace(month=month_plus, day=dt.day - i)
        except ValueError:
            continue
    def addDay(date, number):
        for i in range(number)
            #try to add a day
            try:
                date = date.replace(day = date.day + 1)
            #in case it's impossible ex:january 32nd add a month and restart at day 1
            except:
                #add month part
                try:
                    date = date.replace(month = date.month +1, day = 1)
                except:
                    date = date.replace(year = date.year +1, month = 1, day = 1)

写给还在读这篇文章的人。我认为这段代码更加清晰,特别是与使用模(%)的代码相比。

很抱歉有语法错误,英语不是我的主要语言

我使用这个函数来更改年和月,但保留日:

def replace_month_year(date1, year2, month2):
    try:
        date2 = date1.replace(month = month2, year = year2)
    except:
        date2 = datetime.date(year2, month2 + 1, 1) - datetime.timedelta(days=1)
    return date2

你应该这样写:

new_year = my_date.year + (my_date.month + 6) / 12
new_month = (my_date.month + 6) % 12
new_date = replace_month_year(my_date, new_year, new_month)

修改了Johannes Wei在1new_month = 121情况下的答案。这对我来说非常合适。月份可以是正的,也可以是负的。

def addMonth(d,months=1):
    year, month, day = d.timetuple()[:3]
    new_month = month + months
    return datetime.date(year + ((new_month-1) / 12), (new_month-1) % 12 +1, day)

你说6个月是什么意思?

2009-02-13 + 6个月== 2009-08-13?还是2009-02-13 + 6*30天?

import mx.DateTime as dt

#6 Months
dt.now()+dt.RelativeDateTime(months=6)
#result is '2009-08-13 16:28:00.84'

#6*30 days
dt.now()+dt.RelativeDateTime(days=30*6)
#result is '2009-08-12 16:30:03.35'

更多关于mx的信息。DateTime