A ma connaissance, en Python, à l'aide de la méthode timedelta du module datetime, il est très facile d'ajouter ou de retrancher des jours à une date mais quand il s'agit de le faire avec des mois, les choses se compliquent.
En effet tous les mois n'ayant pas le même nombre de jours, il devient incertain d'utiliser cette méthode.
J'ai donc développé cette fonction getNMonthsLessOrMore qui utilise à la fois le module datetime et le module calendar pour arriver au résultat souhaité.
from datetime import datetime
import calendar
def getNMonthsLessOrMore(startDate : datetime, nbMonths : int) -> list:
class DateTimeFormat(Exception):
pass
class NbMonthsFormat(Exception):
pass
def getDayOfMonth(year, month, day):
tmpCal = list(calendar.Calendar().itermonthdays(year, month))
for x in range(day, 0, -1):
if x in tmpCal: return x
return 1
try:
if not isinstance(startDate, datetime): raise DateTimeFormat()
if not isinstance(nbMonths, int): raise NbMonthsFormat()
except DateTimeFormat:
return False, "La date de départ doit être au format datetime.datetime"
except NbMonthsFormat:
return False, "Le nombre de mois doit être un entier positif ou négatif"
else:
if nbMonths == 0: return [startDate]
L = []
tmpDate = datetime(startDate.year, startDate.month, 1)
if nbMonths < 0:
for i in range(0, nbMonths, -1):
y, m = calendar.prevmonth(tmpDate.year, tmpDate.month)
tmpDate = datetime(y, m, getDayOfMonth(y, m, startDate.day))
L.append(tmpDate)
else:
for i in range(0, nbMonths, 1):
y, m = calendar.nextmonth(tmpDate.year, tmpDate.month)
tmpDate = datetime(y, m, getDayOfMonth(y, m, startDate.day))
L.append(tmpDate)
return L
Exécution de la fonction:
>>> getNMonthsLessOrMore(datetime.now(), -6)
[datetime.datetime(2019, 12, 23, 0, 0), datetime.datetime(2019, 11, 23, 0, 0), datetime.datetime(2019, 10, 23, 0, 0), datetime.datetime(2019, 9, 23, 0, 0), datetime.datetime(2019, 8, 23, 0, 0), datetime.datetime(2019, 7, 23, 0, 0)]
>>> getNMonthsLessOrMore(datetime.now(), 8)
[datetime.datetime(2020, 2, 23, 0, 0), datetime.datetime(2020, 3, 23, 0, 0), datetime.datetime(2020, 4, 23, 0, 0), datetime.datetime(2020, 5, 23, 0, 0), datetime.datetime(2020, 6, 23, 0, 0), datetime.datetime(2020, 7, 23, 0, 0), datetime.datetime(2020, 8, 23, 0, 0), datetime.datetime(2020, 9, 23, 0, 0)]
>>> getNMonthsLessOrMore(datetime.now(), 0)
[datetime.datetime(2020, 1, 23, 7, 31, 43, 913244)]