How do I calculate the date six months from the current date using the datetime Python module?
我正在使用datetime python模块。我想从当前日期算起6个月的日期。有人能帮我一下吗?
我想从当前日期起6个月内生成日期的原因是要生成一个审核日期。如果用户将数据输入到系统中,则自输入数据之日起的审查日期为6个月。
我发现这个解决方案是好的。(这将使用python-dateutil扩展名)
1 2 3 4 | from datetime import date from dateutil.relativedelta import relativedelta six_months = date.today() + relativedelta(months=+6) |
这种方法的优点是它可以处理28天、30天、31天等的问题。这在处理业务规则和方案(例如发票生成等)时非常有用。
1 2 3 4 5 | $ date(2010,12,31)+relativedelta(months=+1) datetime.date(2011, 1, 31) $ date(2010,12,31)+relativedelta(months=+2) datetime.date(2011, 2, 28) |
好吧,这取决于你所说的从当前日期算起6个月是什么意思。
使用自然月:
1 | (day, month, year) = (day, (month+6)%12, year+(month+6)/12) |
使用银行定义,6*30:
1 | date += datetime.timedelta(6*30) |
1 2 | import datetime print (datetime.date.today() + datetime.timedelta(6*365/12)).isoformat() |
对于月初计算:
1 2 3 4 | from datetime import timedelta from dateutil.relativedelta import relativedelta end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period) |
"6个月"是什么意思?2009-02-13+6个月=2009-08-13还是2009-02-13+6*30天?
1 2 3 4 5 6 7 8 9 | 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的详细信息
此解决方案在12月份正常工作,而本页上的大多数答案都不正确。在使用模数(%)或整数除(//)之前,您需要首先将月份从基数1(ie jan=1)移到基数0(ie jan=0),否则11月(11)加1个月为12,当找到余数(12%12)时,余数为0。
(不建议)(12月+1"或10月+1=12月!)
1 2 3 4 | def AddMonths(d,x): newmonth = ((( d.month - 1) + x ) % 12 ) + 1 newyear = d.year + ((( d.month - 1) + x ) / 12 ) return datetime.date( newyear, newmonth, d.day) |
然而。。。这并不能解释1月31日+1个月这样的问题。所以我们回到操作-你说增加一个月是什么意思?一个解决办法是回溯到一个有效的日期,因为大多数人会假定1月的最后一天加上一个月等于2月的最后一天。这也适用于负月数。证明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | >>> import datetime >>> AddMonths(datetime.datetime(2010,8,25),1) datetime.date(2010, 9, 25) >>> AddMonths(datetime.datetime(2010,8,25),4) datetime.date(2010, 12, 25) >>> AddMonths(datetime.datetime(2010,8,25),5) datetime.date(2011, 1, 25) >>> AddMonths(datetime.datetime(2010,8,25),13) datetime.date(2011, 9, 25) >>> AddMonths(datetime.datetime(2010,8,25),24) datetime.date(2012, 8, 25) >>> AddMonths(datetime.datetime(2010,8,25),-1) datetime.date(2010, 7, 25) >>> AddMonths(datetime.datetime(2010,8,25),0) datetime.date(2010, 8, 25) >>> AddMonths(datetime.datetime(2010,8,25),-12) datetime.date(2009, 8, 25) >>> AddMonths(datetime.datetime(2010,8,25),-8) datetime.date(2009, 12, 25) >>> AddMonths(datetime.datetime(2010,8,25),-7) datetime.date(2010, 1, 25)>>> |
对于Python的日期时间,没有直接的方法可以做到这一点。
查看python-dateutil中的relativedelta类型。它允许您以月为单位指定时间增量。
所以,这里有一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | >>> 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 |
与其他答案一样,您必须弄清楚"6个月后"的实际含义。如果您的意思是"未来6年内的某个月的今天",那么应该这样做:
1 | datetime.datetime.now() + relativedelta(months=6) |
我知道这是6个月的时间,但是如果你增加一个月,谷歌会给出"在python中增加几个月"的答案:
1 2 3 4 5 | import calendar date = datetime.date.today() //Or your date datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1]) |
这将计算当前月份中的天数并将其添加到当前日期,使用365/12,如果您重复日期,一年中的1/12可能会导致短/长月份的问题。
使用python 3.x,您可以这样做:
1 2 3 4 5 6 7 8 9 10 | 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 |
但您需要安装python dateutil模块:
1 | pip install python-dateutil |
只需使用TimeTuple方法提取月份,添加月份并构建一个新的DateObject。如果已经有了这种方法,我就不知道了。
1 2 3 4 5 6 | 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个月等角落案件。:)
dateutil包实现了这类功能。但要知道,这将是幼稚的,正如其他人已经指出的。
使用python标准库,即不使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
测试:
1 2 3 4 5 6 7 | >>>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)) |
我有更好的方法来解决"2月31日"的问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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) |
我认为它也适用于负数(减去月份),但我没有做过很多测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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))) |
pyqt4的qdate类具有addmonths函数。
1 2 3 4 5 6 7 8 9 | >>>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) |
这个怎么样?不使用其他库(
1 2 3 4 | import datetime today = datetime.date.today() six_months_from_today = datetime.date(today.year + (today.month + 6)/12, (today.month + 6) % 12, today.day) |
我试过使用
1 2 3 4 5 6 | day = datetime.date(2015, 3, 10) print day >>> 2015-03-10 print (day + datetime.timedelta(6*365/12)) >>> 2015-09-08 |
我认为,我们通常假定从某一天起的6个月将在该月的同一天着陆,但6个月后着陆(即
我希望你觉得这有帮助。
已修改addMonths(),以便在Zope中使用并处理无效的日期:
1 2 3 4 5 6 7 8 9 | 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) |
获取x个月之后/之前的下一个日期的常规函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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) |
假设您的日期时间变量称为日期:
1 2 3 | 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) |
下面是一个示例,它允许用户决定如何返回一个日期,其中日期大于月份中的天数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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) |
修改了Johannes Wei在案例1"新月份=121"中的回答。这对我很有效。月份可以是正的也可以是负的。
1 2 3 4 | 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) |
从这个答案中,请参见ParseDateTime。下面是代码示例。更多细节:单元测试中有许多自然语言->YYYY-MM-DD转换示例,以及明显的ParseDateTime转换挑战/错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #!/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') |
上述代码从MacOSX机器生成以下内容:
1 2 3 4 | $ ./parsedatetime_simple.py today's date = Wednesday, 2015-05-13 6 months -> 2015-11-13 $ |
我这样解决了这个问题:
1 2 3 4 5 6 7 8 9 10 11 | import calendar from datetime import datetime moths2add = 6 now = datetime.now() current_year = now.year current_month = now.month #count days in months you want to add using calendar module days = sum( [calendar.monthrange(current_year, elem)[1] for elem in range(current_month, current_month + moths)] ) print now + days |
还有另一个解决方案-希望有人会喜欢它:
1 2 | def add_months(d, months): return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12) |
对于所有情况,此解决方案在第29、30、31天内都不起作用,因此需要更强大的解决方案(不再那么好了:):
1 2 3 4 5 6 7 8 | 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") |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 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)) |
这就是我想到的。它移动了正确的月份和年份,但忽略了天数(这是我在这种情况下需要的)。
1 2 3 4 5 6 7 8 9 | import datetime month_dt = 4 today = datetime.date.today() y,m = today.year, today.month m += month_dt-1 year_dt = m//12 new_month = m%12 new_date = datetime.date(y+year_dt, new_month+1, 1) |
我使用
1 2 3 4 5 6 7 8 9 10 11 12 | def month_timedelta(dt, m): y = m // 12 dm = m % 12 if y == 0: if dt.month + m <= 12: return dt.replace(month = dt.month + m) else: dy = (dt.month + m) // 12 ndt = dt.replace(year=dt.year + dy) return ndt.replace(month=(ndt.month + m) % 12) else: return month_timedelta(dt.replace(year=dt.year + y),dm) |
用户417751修改了先前的答案。也许不是用Python的方式,但它需要处理不同的月份长度和闰年。在这种情况下,2012年1月31日+1个月=2012年2月29日。
1 2 3 4 5 6 7 8 9 10 11 12 | 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) |
另一种解决方案是:计算下一个n个月的月份天数总和,并将结果添加到当前日期。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import calendar import datetime def date_from_now(months): today = datetime.datetime.today() month = today.month year = today.year sum_days = 0 for i in range(int(months)): month += 1 if month == 13: month = 1 year += 1 sum_days += calendar.monthrange(year, month)[1] return datetime.date.today() + datetime.timedelta(sum_days) print(date_from_now(12)) # if to day is 2017-01-01, output: 2019-01-01 |
我迟到了,但是
查看ken reitz maya模块,
https://github.com/kennethreitz/maya
这样可以帮助您,只需将hours=1改为days=1或years=1
1 2 3 4 5 6 7 | >>> from maya import MayaInterval # Create an event that is one hour long, starting now. >>> event_start = maya.now() >>> event_end = event_start.add(hours=1) >>> event = MayaInterval(start=event_start, end=event_end) |
我使用此功能更改年和月,但保留日:
1 2 3 4 5 6 | 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 |
你应该写:
1 2 3 | 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) |
使用python datetime模块向datetime.today()添加6个月的时间增量。
http://docs.python.org/library/datetime.html网站
你当然要解决魏先生提出的问题吗?--你说6个月是什么意思?
我认为这样做会更安全,而不是手动增加天数:
1 2 3 4 5 6 7 8 9 10 11 12 | 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) |
当我需要添加月或年并且不想导入更多的库时,这就是我要做的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 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)添加一年。
我修改了Tony Diep的答案,可能稍微优雅一些(当然是python 2,匹配问题的日期和原始答案,对于python 3,根据需要进行修改,至少包括
1 2 3 4 5 6 7 8 9 10 11 12 | def add_months(date, months): month = date.month + months - 1 year = date.year + (month / 12) month = (month % 12) + 1 day = date.day while (day > 0): try: new_date = date.replace(year=year, month=month, day=day) break except: day = day - 1 return new_date |
根据"业务需求"的解释添加月份,日期映射超过月底后,应映射到月底,而不是下个月。
我们可能应该使用dateutil.relativedelta
不过,为了学术上的兴趣,我会补充一点,在我发现它之前,我打算使用这个:
尝试:&vexpdt=k.today.replace(k.today.year+(k.today.month+6)//12(k.today.month+5)%12+1,k.today.day)除:&vexpdt=k.today.replace(k.today.year+(k.today.month+6)//12,(k.today.month+6)%12+1,1)-时间差(days=1)
这看起来很简单,但仍然抓住了所有问题,如29、30、31
它还可以通过做-时间增量工作-6个月
注意-不要被k混淆。今天它只是我程序中的一个变量。
在这个函数中,n可以是正的,也可以是负的。
1 2 3 4 | def addmonth(d, n): n += 1 dd = datetime.date(d.year + n/12, d.month + n%12, 1)-datetime.timedelta(1) return datetime.date(dd.year, dd.month, min(d.day, dd.day)) |
使用下面给出的函数,您可以获得x个月之后/之前的日期。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | from datetime import date def next_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 = next_month(today, mm) print(next_date) |
我找不到这个问题的确切解决方案,所以我将发布我的解决方案,以防使用stantard日历和datetime libs有任何帮助。这适用于加和减月份,并说明月末滚动和最后一个月的天数少于最初一个月的情况。我还有一个更通用的解决方案,如果你想寻找更复杂的操作,它会增加规则的间隔(天、月、年、季度、字长等),比如:"1米"、"-9米"、"-1.5年"、"-3q"、"1秒"等等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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) |
1 2 3 4 5 6 7 8 9 10 11 12 | 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) |
对于每个仍在阅读这篇文章的人。我认为这段代码要清楚得多,特别是与使用modulo%的代码相比。
对不起,任何语法错误,英语不是我的主要语言