import re, datetime
def add_months(datestr, months):
ref_year, ref_month = "", ""
ref_year_is_leap_year = False
aux_date = str(datetime.datetime.strptime(datestr, "%Y-%m-%d"))
print(repr(aux_date))
for i_month in range(int(months)):
# I add a unit since the months are "numerical quantities",
# that is, they are expressed in natural numbers, so I need it
# to start from 1 and not from 0 like the iter variable in python
i_month = i_month + 1
m1 = re.search(
r"(?P<year>\d*)-(?P<month>\d{2})-(?P<startDay>\d{2})",
aux_date,
re.IGNORECASE,
)
if m1:
ref_year, ref_month = (
str(m1.groups()[0]).strip(),
str(m1.groups()[1]).strip(),
)
number_of_days_in_each_month = {
"01": "31",
"02": "28",
"03": "31",
"04": "30",
"05": "31",
"06": "30",
"07": "31",
"08": "31",
"09": "30",
"10": "31",
"11": "30",
"12": "31",
}
n_days_in_this_i_month = number_of_days_in_each_month[ref_month]
print(n_days_in_this_i_month) # nro days to increment in each i month iteration
if (
int(ref_year) % 4 == 0
and int(ref_year) % 100 == 0
and int(ref_year) % 400 != 0
):
ref_year_is_leap_year = True # divisible entre 4 y 10 y no entre 400, para determinar que sea un año bisciesto
if ref_year_is_leap_year == True and ref_month == "02":
n_days_in_this_i_month = str(int(n_days_in_this_i_month) + 1) # 28 --> 29
aux_date = (
datetime.datetime.strptime(datestr, "%Y-%m-%d")
+ datetime.timedelta(days=int(n_days_in_this_i_month))
).strftime("%Y-%m-%d")
print(repr(aux_date))
return aux_date
print(repr(add_months("2022-12-30", "3")))
Why does the aux_date variable, instead of progressively increasing the number of days of the elapsed months, only limit itself to adding 31 days of that month of January, and then add them back to the original amount, staying stuck there instead of advancing each iteration of this for loop?
The objective of this for loop is to achieve an incremental iteration loop where the days are added and not one that always returns to the original amount to add the same content over and over again.
Updated function Algorithm
In this edit I have modified some details and redundancies, and also fixed some bugs that are present in the original code.
def add_months(datestr, months):
ref_year, ref_month = "", ""
ref_year_is_leap_year = False #condicional booleano, cuya logica binaria intenta establecer si es o no bisiesto el año tomado como referencia
aux_date = datetime.datetime.strptime(datestr, "%Y-%m-%d")
for i_month in range(int(months)):
i_month = i_month + 1 # I add a unit since the months are "numerical quantities", that is, they are expressed in natural numbers, so I need it to start from 1 and not from 0 like the iter variable in python
m1 = re.search( r"(?P<year>\d*)-(?P<month>\d{2})-(?P<startDay>\d{2})", str(aux_date), re.IGNORECASE, )
if m1:
ref_year, ref_month = ( str(m1.groups()[0]).strip(), str( int(m1.groups()[1]) + 1).strip(), )
if( len(ref_month) == 1 ): ref_month = "0" + ref_month
if( int(ref_month) > 12 ): ref_month = "01"
print(ref_month)
number_of_days_in_each_month = {
"01": "31",
"02": "28",
"03": "31",
"04": "30",
"05": "31",
"06": "30",
"07": "31",
"08": "31",
"09": "30",
"10": "31",
"11": "30",
"12": "31",
}
n_days_in_this_i_month = number_of_days_in_each_month[ref_month]
if ( int(ref_year) % 4 == 0 and int(ref_year) % 100 != 0 ) or ( int(ref_year) % 400 == 0 ): ref_year_is_leap_year = True ref_year_is_leap_year = True # divisible entre 4 y 10 y no entre 400, para determinar que sea un año bisciesto
if ref_year_is_leap_year == True and ref_month == "02": n_days_in_this_i_month = str(int(n_days_in_this_i_month) + 1) # 28 --> 29
print(n_days_in_this_i_month) # nro days to increment in each i month iteration
aux_date = aux_date + datetime.timedelta(days=int(n_days_in_this_i_month))
return datetime.datetime.strftime(aux_date, "%Y-%m-%d")
blackauto-formatter on your code to make it more legible. I also fixed some spacing issues, and spread the comment over multiple lines (this was making the autoformatted result very janky with one very long comment line). Try to stick to the PEP8 style conventions to make your code more legible by other people: peps.python.org/pep-0008dateutil.relativedeltato add monthsdatestr.