如何使用datetime Python模块计算距离当前日期六个月的日期?

如何使用datetime Python模块计算距离当前日期六个月的日期?,python,datetime,Python,Datetime,我正在使用datetime Python模块。我希望从当前日期算起6个月后的日期。谁能帮我一点忙吗 我希望从当前日期开始6个月后生成一个日期的原因是生成一个审阅日期。如果用户在系统中输入数据,则审查日期为自用户输入数据之日起6个月 你说的“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)

我正在使用datetime Python模块。我希望从当前日期算起6个月后的日期。谁能帮我一点忙吗

我希望从当前日期开始6个月后生成一个日期的原因是生成一个审阅日期。如果用户在系统中输入数据,则审查日期为自用户输入数据之日起6个月

你说的“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'
有关

的更多信息只需使用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个月这样的极端情况

具有此类功能的实现。但是请注意,正如其他人已经指出的那样,这将是幼稚的。

使用Python的datetime无法直接做到这一点


查看位于的relativedelta类型。它允许您以月为单位指定时间增量。

好吧,这取决于从当前日期算起6个月的含义

  • 使用自然月:

    (day, month, year) = (day, (month + 5) % 12 + 1, year + (month + 5)/12)
    
  • 按照银行家的定义,6*30:

    date += datetime.timedelta(6 * 30)
    

  • PyQt4的QDate类具有addmonths函数

    >>>from PyQt4.QtCore import QDate  
    >>>dt = QDate(2009,12,31)  
    >>>required = dt.addMonths(6) 
    
    >>>required
    PyQt4.QtCore.QDate(2010, 6, 30)
    
    >>>required.toPyDate()
    datetime.date(2010, 6, 30)
    

    修改了Johannes Wei在案例1 New_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)
    

    这就是我想到的。它移动了正确的月数和年数,但忽略了天数(在我的情况下,这正是我所需要的)


    我使用此功能更改年份和月份,但保留日期:

    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)
    

    因此,这里有一个
    dateutil.relativedelta
    的示例,我发现它对于迭代过去一年非常有用,每次跳过一个月直到现在:

    >>> import datetime
    >>> from dateutil.relativedelta import relativedelta
    >>> today = datetime.datetime.today()
    >>> month_count = 0
    >>> while month_count < 12:
    ...  day = today - relativedelta(months=month_count)
    ...  print day
    ...  month_count += 1
    ... 
    2010-07-07 10:51:45.187968
    2010-06-07 10:51:45.187968
    2010-05-07 10:51:45.187968
    2010-04-07 10:51:45.187968
    2010-03-07 10:51:45.187968
    2010-02-07 10:51:45.187968
    2010-01-07 10:51:45.187968
    2009-12-07 10:51:45.187968
    2009-11-07 10:51:45.187968
    2009-10-07 10:51:45.187968
    2009-09-07 10:51:45.187968
    2009-08-07 10:51:45.187968
    

    此解决方案适用于12月份,但本页上的大多数答案都不适用。 在使用模数(%)或整数除法(/)之前,您需要首先将月份从基数1(即Jan=1)移到基数0(即Jan=0),否则11月(11日)加1个月将得到12,在查找余数(12%12)时将得到0

    (并且不要建议“(12个月)+1”或10月+1=12月!)

    然而。。。这并不能解释像1月31日+一个月这样的问题。那么我们回到OP——你说增加一个月是什么意思?一种解决方法是回溯到一个有效的日期,因为大多数人都认为1月的最后一天加上一个月等于2月的最后一天。 这也适用于负数月。 证明:


    我发现这个解决方案很好。(这使用了

    这种方法的优点是它可以处理28天、30天、31天等的问题。这在处理业务规则和场景(例如发票生成等)时非常有用


    我认为这样做比手动增加天数更安全:

    import datetime
    today = datetime.date.today()
    
    def addMonths(dt, months = 0):
        new_month = months + dt.month
        year_inc = 0
        if new_month>12:
            year_inc +=1
            new_month -=12
        return dt.replace(month = new_month, year = dt.year+year_inc)
    
    newdate = addMonths(today, 6)
    
    导入日期时间
    '''
    创建于2011-03-09
    @作者:tonydiep
    '''
    def添加业务月份(开始日期、月份到添加):
    """
    按照商务人士对月份的看法添加月份。
    2011年1月31日+1个月=2011年2月28日商业人士
    方法:添加月数,回滚日期,直到它成为有效日期
    """
    #确定年份
    年\变更=月\添加/12
    #确定增加月份是否有结转
    如果(开始日期月+(月到月添加%12)>12):
    年份变化=年份变化+1
    新年份=开始日期。年份+年份更改
    #确定月份
    工作=月数加上%12
    如果0==工时:
    新月份=开始日期。月份
    其他:
    新月份=(开始日期.月份+(工作%12))%12
    如果0==新月份:
    新月份=12
    #确定月份的哪一天
    新建日期=开始日期.day
    如果(在[31,30,29,28]中的新的一天):
    #用户表示月底
    新工作日=31
    新日期=无
    而(无==新建日期,27<新建日期):
    尝试:
    新建日期=开始日期。替换(年=新建年,月=新建月,日=新建日)
    除:
    new_day=new_day-1#放松直到找到有效日期
    返回新日期
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    #测验
    日期=[datetime.date(2011年1月31日),
    日期时间。日期(2011年2月28日),
    日期时间。日期(2011年3月28日),
    日期时间。日期(2011年4月28日),
    日期时间。日期(2011年5月28日),
    日期时间。日期(2011年6月28日),
    日期时间。日期(2011年7月28日),
    日期时间。日期(2011年8月28日),
    日期时间。日期(2011年9月28日),
    日期时间。日期(2011年10月28日),
    日期时间。日期(2011年11月28日),
    日期时间。日期(2011年12月28日),
    ]
    月份=范围(1,24)
    对于日期中的开始日期:
    以月为单位的m:
    结束日期=增加业务月数(开始日期,m)
    打印(“%s\t%s\t%s”%(开始日期,结束日期,m))
    
    我知道这是6个月,但是如果您要添加一个月,则在google中会显示“在python中添加月”的答案:

    import calendar
    
    date = datetime.date.today()    //Or your date
    
    datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])
    

    这将计算当前月份的天数并将其添加到当前日期,如果您在日期上迭代,则使用365/12将导致一年中的1/12可能会导致短/长月份出现问题。

    我有一个更好的方法来解决“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)
    
    import datetime
    import calendar
    
    def add_months(date, months):
        months_count = date.month + months
    
        # Calculate the year
        year = date.year + int(months_count / 12)
    
        # Calculate the month
        month = (months_count % 12)
        if month == 0:
            month = 12
    
        # Calculate the day
        day = date.day
        last_day_of_month = calendar.monthrange(year, month)[1]
        if day > last_day_of_month:
            day = last_day_of_month
    
        new_date = datetime.date(year, month, day)
        return new_date
    
    我认为它也适用于负数(减去月数),但我没有对此进行过太多测试。

    修改了AddMonths()以用于Zope和处理无效的日数:

    def AddMonths(d,x):
        days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        newmonth = ((( d.month() - 1) + x ) % 12 ) + 1
        newyear  = d.year() + ((( d.month() - 1) + x ) // 12 ) 
        if d.day() > days_of_month[newmonth-1]:
          newday = days_of_month[newmonth-1]
        else:
          newday = d.day() 
        return DateTime( newyear, newmonth, newday)
    

    另一个解决方案-希望有人会喜欢:

    def add_months(d, months):
        return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12)
    
    此解决方案在29、30、31天内不能适用于所有情况,因此需要更健壮的解决方案(不再那么好了:):

    从,看。下面是代码示例。更多细节:,显而易见

    上面的代码从
    import datetime
    today = datetime.date.today()
    
    def addMonths(dt, months = 0):
        new_month = months + dt.month
        year_inc = 0
        if new_month>12:
            year_inc +=1
            new_month -=12
        return dt.replace(month = new_month, year = dt.year+year_inc)
    
    newdate = addMonths(today, 6)
    
    import datetime
    
    
    '''
    Created on 2011-03-09
    
    @author: tonydiep
    '''
    
    def add_business_months(start_date, months_to_add):
        """
        Add months in the way business people think of months. 
        Jan 31, 2011 + 1 month = Feb 28, 2011 to business people
        Method: Add the number of months, roll back the date until it becomes a valid date
        """
        # determine year
        years_change = months_to_add / 12
    
        # determine if there is carryover from adding months
        if (start_date.month + (months_to_add % 12) > 12 ):
            years_change = years_change + 1
    
        new_year = start_date.year + years_change
    
        # determine month
        work = months_to_add % 12
        if 0 == work:
            new_month = start_date.month
        else:
            new_month = (start_date.month + (work % 12)) % 12
    
        if 0 == new_month:
            new_month = 12 
    
        # determine day of the month
        new_day = start_date.day
        if(new_day in [31, 30, 29, 28]):
            #user means end of the month
            new_day = 31
    
    
        new_date = None
        while (None == new_date and 27 < new_day):
            try:
                new_date = start_date.replace(year=new_year, month=new_month, day=new_day)
            except:
                new_day = new_day - 1   #wind down until we get to a valid date
    
        return new_date
    
    
    if __name__ == '__main__':
        #tests
        dates = [datetime.date(2011, 1, 31),
                 datetime.date(2011, 2, 28),
                 datetime.date(2011, 3, 28),
                 datetime.date(2011, 4, 28),
                 datetime.date(2011, 5, 28),
                 datetime.date(2011, 6, 28),
                 datetime.date(2011, 7, 28),
                 datetime.date(2011, 8, 28),
                 datetime.date(2011, 9, 28),
                 datetime.date(2011, 10, 28),
                 datetime.date(2011, 11, 28),
                 datetime.date(2011, 12, 28),
                 ]
        months = range(1, 24)
        for start_date in dates:
            for m in months:
                end_date = add_business_months(start_date, m)
                print("%s\t%s\t%s" %(start_date, end_date, m))
    
    import calendar
    
    date = datetime.date.today()    //Or your date
    
    datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])
    
    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)
    
    def AddMonths(d,x):
        days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        newmonth = ((( d.month() - 1) + x ) % 12 ) + 1
        newyear  = d.year() + ((( d.month() - 1) + x ) // 12 ) 
        if d.day() > days_of_month[newmonth-1]:
          newday = days_of_month[newmonth-1]
        else:
          newday = d.day() 
        return DateTime( newyear, newmonth, newday)
    
    import time
    
    def add_month(start_time, months):  
    
            ret = time.strptime(start_time, '%Y-%m-%d')
            t = list(ret)
    
            t[1] += months
    
            if t[1] > 12:
                t[0] += 1 + int(months / 12)
    
                t[1] %= 12
    
            return int(time.mktime(tuple(t)))
    
    def add_months(d, months):
        return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12)
    
    def add_months(d, months):
        for i in range(4):
            day = d.day - i
            try:
                return d.replace(day=day).replace(year=d.year+int(months)//12).replace(month=(d.month+int(months))%12)
            except:
                pass
        raise Exception("should not happen")
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import time, calendar
    from datetime import date
    
    # from https://github.com/bear/parsedatetime
    import parsedatetime as pdt
    
    def print_todays_date():
        todays_day_of_week = calendar.day_name[date.today().weekday()]
        print "today's date = " + todays_day_of_week + ', ' + \
                                  time.strftime('%Y-%m-%d')
    
    def convert_date(natural_language_date):
        cal = pdt.Calendar()
        (struct_time_date, success) = cal.parse(natural_language_date)
        if success:
            formal_date = time.strftime('%Y-%m-%d', struct_time_date)
        else:
            formal_date = '(conversion failed)'
        print '{0:12s} -> {1:10s}'.format(natural_language_date, formal_date)
    
    print_todays_date()
    convert_date('6 months')
    
    $ ./parsedatetime_simple.py 
    today's date = Wednesday, 2015-05-13
    6 months     -> 2015-11-13
    $ 
    
    import datetime
    
    today = datetime.date.today()
    six_months_from_today = datetime.date(today.year + (today.month + 6)/12, (today.month + 6) % 12, today.day)
    
    day = datetime.date(2015, 3, 10)
    print day
    >>> 2015-03-10
    
    print (day + datetime.timedelta(6*365/12))
    >>> 2015-09-08
    
    def add_months(date, months, endOfMonthBehaviour='RoundUp'):
        assert endOfMonthBehaviour in ['RoundDown', 'RoundIn', 'RoundOut', 'RoundUp'], \
            'Unknown end of month behaviour'
        year = date.year + (date.month + months - 1) / 12
        month = (date.month + months - 1) % 12 + 1
        day = date.day
        last = monthrange(year, month)[1]
        if day > last:
            if endOfMonthBehaviour == 'RoundDown' or \
                endOfMonthBehaviour == 'RoundOut' and months < 0 or \
                endOfMonthBehaviour == 'RoundIn' and months > 0:
                day = last
            elif endOfMonthBehaviour == 'RoundUp' or \
                endOfMonthBehaviour == 'RoundOut' and months > 0 or \
                endOfMonthBehaviour == 'RoundIn' and months < 0:
                # we don't need to worry about incrementing the year
                # because there will never be a day in December > 31
                month += 1
                day = 1
        return datetime.date(year, month, day)
    
    
    >>> from calendar import monthrange
    >>> import datetime
    >>> add_months(datetime.datetime(2016, 1, 31), 1)
    datetime.date(2016, 3, 1)
    >>> add_months(datetime.datetime(2016, 1, 31), -2)
    datetime.date(2015, 12, 1)
    >>> add_months(datetime.datetime(2016, 1, 31), -2, 'RoundDown')
    datetime.date(2015, 11, 30)
    
    from datetime import timedelta
    from dateutil.relativedelta import relativedelta
    
    end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)
    
    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)
    
    from datetime import date def after_month(given_date, month): yyyy = int(((given_date.year * 12 + given_date.month) + month)/12) mm = int(((given_date.year * 12 + given_date.month) + month)%12) if mm == 0: yyyy -= 1 mm = 12 return given_date.replace(year=yyyy, month=mm) if __name__ == "__main__": today = date.today() print(today) for mm in [-12, -1, 0, 1, 2, 12, 20 ]: next_date = after_month(today, mm) print(next_date)
    import datetime
    import calendar
    
    def add_months(date, months):
        months_count = date.month + months
    
        # Calculate the year
        year = date.year + int(months_count / 12)
    
        # Calculate the month
        month = (months_count % 12)
        if month == 0:
            month = 12
    
        # Calculate the day
        day = date.day
        last_day_of_month = calendar.monthrange(year, month)[1]
        if day > last_day_of_month:
            day = last_day_of_month
    
        new_date = datetime.date(year, month, day)
        return new_date
    
    >>>date = datetime.date(2018, 11, 30)
    
    >>>print(date, add_months(date, 3))
    (datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))
    
    >>>print(date, add_months(date, 14))
    (datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))
    
    from datetime import datetime, timedelta
    from dateutil.relativedelta import *
    
    date = datetime.now()
    print(date)
    # 2018-09-24 13:24:04.007620
    
    date = date + relativedelta(months=+6)
    print(date)
    # 2019-03-24 13:24:04.007620
    
    pip install python-dateutil
    
    >>> import arrow
    
    >>> arrow.now().date()
    datetime.date(2019, 6, 28)
    >>> arrow.now().shift(months=6).date()
    datetime.date(2019, 12, 28)
    
    from datetime import datetime
    from calendar import monthrange
    
    # Time to increase (in months)
    inc = 12
    
    # Returns mod of the division for 12 (months)
    month = ((datetime.now().month + inc) % 12) or 1
    
    # Increase the division by 12 (months), if necessary (+ 12 months increase)
    year = datetime.now().year + int((month + inc) / 12)
    
    # (IF YOU DON'T NEED DAYS,CAN REMOVE THE BELOW CODE)
    # Returns the same day in new month, or the maximum day of new month
    day = min(datetime.now().day,monthrange(year, month)[1])
    
    print("Year: {}, Month: {}, Day: {}".format(year, month, day))