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

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


当前回答

user417751之前回答的重做。也许不是那么python的方式,但它照顾到不同的月份长度和闰年。在本例中,2012年1月31日+ 1个月= 2012年2月29日。

import datetime
import calendar

def add_mths(d, x):
    newday = d.day
    newmonth = (((d.month - 1) + x) % 12) + 1
    newyear  = d.year + (((d.month - 1) + x) // 12)
    if newday > calendar.mdays[newmonth]:
        newday = calendar.mdays[newmonth]
        if newyear % 4 == 0 and newmonth == 2:
            newday += 1
    return datetime.date(newyear, newmonth, newday)

其他回答

只需使用timetuple方法提取月份,添加您的月份并构建一个新的dateobject。如果有一个已经存在的方法,我不知道它。

import datetime

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

这个API有点笨拙,但可以作为示例使用。这显然也不适用于像2008-01-31 + 1个月这样的极端情况。:)

我找不到这个问题的确切解决方案,所以我将发布我的解决方案,以防使用标准日历和datetime库可能有任何帮助。这适用于添加和减去月份,并考虑月末滚动和最后一个月比第一个月天数少的情况。如果你正在寻找更复杂的操作,我还有一个更通用的解决方案,它添加了定期间隔(天,月,年,季度,学期等),如:“1m”,“-9m”,“-1.5y”,“-3q”,“1s”等。

from datetime import datetime
from calendar import monthrange
def date_bump_months(start_date, months):
    """
    bumps months back and forth. 
    --> if initial date is end-of-month, i will move to corresponding month-end
    --> ir inital date.day is greater than end of month of final date, it casts it to momth-end
    """
    signbit = -1 if months < 0 else 1
    d_year, d_month = divmod(abs(months),12)    
    end_year = start_date.year + d_year*signbit 
    end_month = 0
    if signbit ==-1:            
        if d_month < start_date.month:
            end_month = start_date.month - d_month
        else:
            end_year -=1
            end_month = 12 - (d_month - start_date.month)
    else:
        end_month +=start_date.month
        if end_month  > 12:
            end_year +=1
            end_month -=12
    # check if we are running end-of-month dates
    eom_run = monthrange(start_date.year, start_date.month)[1]==start_date.day
    eom_month = monthrange((end_year), (end_month))[1]
    if eom_run:
        end_day = eom_month 
    else:
        end_day = min(start_date.day, eom_month )    
    return date(end_year, end_month, end_day)

当我需要添加几个月或几年的时间,并且不想导入更多的库时,我就会这样做。

import datetime
__author__ = 'Daniel Margarido'


# Check if the int given year is a leap year
# return true if leap year or false otherwise
def is_leap_year(year):
    if (year % 4) == 0:
        if (year % 100) == 0:
            if (year % 400) == 0:
                return True
            else:
                return False
        else:
            return True
    else:
        return False


THIRTY_DAYS_MONTHS = [4, 6, 9, 11]
THIRTYONE_DAYS_MONTHS = [1, 3, 5, 7, 8, 10, 12]

# Inputs -> month, year Booth integers
# Return the number of days of the given month
def get_month_days(month, year):
    if month in THIRTY_DAYS_MONTHS:   # April, June, September, November
        return 30
    elif month in THIRTYONE_DAYS_MONTHS:   # January, March, May, July, August, October, December
        return 31
    else:   # February
        if is_leap_year(year):
            return 29
        else:
            return 28

# Checks the month of the given date
# Selects the number of days it needs to add one month
# return the date with one month added
def add_month(date):
    current_month_days = get_month_days(date.month, date.year)
    next_month_days = get_month_days(date.month + 1, date.year)

    delta = datetime.timedelta(days=current_month_days)
    if date.day > next_month_days:
        delta = delta - datetime.timedelta(days=(date.day - next_month_days) - 1)

    return date + delta


def add_year(date):
    if is_leap_year(date.year):
        delta = datetime.timedelta(days=366)
    else:
        delta = datetime.timedelta(days=365)

    return date + delta


# Validates if the expected_value is equal to the given value
def test_equal(expected_value, value):
    if expected_value == value:
        print "Test Passed"
        return True

    print "Test Failed : " + str(expected_value) + " is not equal to " str(value)
    return False

# Test leap year
print "---------- Test leap year ----------"
test_equal(True, is_leap_year(2012))
test_equal(True, is_leap_year(2000))
test_equal(False, is_leap_year(1900))
test_equal(False, is_leap_year(2002))
test_equal(False, is_leap_year(2100))
test_equal(True, is_leap_year(2400))
test_equal(True, is_leap_year(2016))

# Test add month
print "---------- Test add month ----------"
test_equal(datetime.date(2016, 2, 1), add_month(datetime.date(2016, 1, 1)))
test_equal(datetime.date(2016, 6, 16), add_month(datetime.date(2016, 5, 16)))
test_equal(datetime.date(2016, 3, 15), add_month(datetime.date(2016, 2, 15)))
test_equal(datetime.date(2017, 1, 12), add_month(datetime.date(2016, 12, 12)))
test_equal(datetime.date(2016, 3, 1), add_month(datetime.date(2016, 1, 31)))
test_equal(datetime.date(2015, 3, 1), add_month(datetime.date(2015, 1, 31)))
test_equal(datetime.date(2016, 3, 1), add_month(datetime.date(2016, 1, 30)))
test_equal(datetime.date(2016, 4, 30), add_month(datetime.date(2016, 3, 30)))
test_equal(datetime.date(2016, 5, 1), add_month(datetime.date(2016, 3, 31)))

# Test add year
print "---------- Test add year ----------"
test_equal(datetime.date(2016, 2, 2), add_year(datetime.date(2015, 2, 2)))
test_equal(datetime.date(2001, 2, 2), add_year(datetime.date(2000, 2, 2)))
test_equal(datetime.date(2100, 2, 2), add_year(datetime.date(2099, 2, 2)))
test_equal(datetime.date(2101, 2, 2), add_year(datetime.date(2100, 2, 2)))
test_equal(datetime.date(2401, 2, 2), add_year(datetime.date(2400, 2, 2)))

只需创建一个datetime.date()对象,调用add_month(date)来添加一个月,调用add_year(date)来添加一个年。

使用python datetime模块为datetime.today()添加6个月的时间增量。

http://docs.python.org/library/datetime.html

你当然要解决Johannes weß提出的问题——你说的6个月是什么意思?

假设你的datetime变量叫做date:

date=datetime.datetime(year=date.year+int((date.month+6)/12),
                       month=(date.month+6)%13 + (1 if (date.month + 
                       months>12) else 0), day=date.day)