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")))

为什么aux_date变量,而不是progressively increasing,过go 月份的天数,只限于将1月份的31天相加,然后将它们添加回原始数量,停留在那里,而不是推进for循环的每个迭代?

这个for循环的目标是实现一个incremental iteration loop,其中添加了天数,而不是总是返回到原始数量来反复添加相同的内容.


Updated function 算法rithm

在这次编辑中,我修改了一些细节和冗余,还修复了原始代码中存在的一些错误.

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")

推荐答案

因此,正如Alexander的答案已经确定的那样,您没有更新日期,所以您总是在每次迭代中添加相同的开始日期.我擅自清理了您的代码,使用正则表达式和字符串之间来回转换,使用int‘s是完全错误的方法--它遗漏了Date-Time对象的entire point,即将信息封装在Date中.只需使用这些对象,not strings.下面是与仅使用datetime.datetime个对象的代码相同的方法:

import datetime

def add_months(datestr, months):

    number_of_days_in_each_month = {
            1 : 31,
            2 : 28,
            3 : 31,
            4: 30,
            5: 31,
            6: 30,
            7: 31,
            8: 31,
            9: 30,
            10: 31,
            11: 30,
            12: 31,
    }

    date = datetime.datetime.strptime(datestr, "%Y-%m-%d")
    is_leap_year = False

    for i_month in range(1, int(months) + 1):

        ref_year, ref_month = date.year, date.month

        n_days = number_of_days_in_each_month[ref_month]

        if (
            ref_year % 4 == 0
            and ref_year % 100 == 0
            and ref_year % 400 != 0
        ):
            is_leap_year = True  # divisible entre 4 y 10 y no entre 400, para determinar que sea un año bisciesto

        if is_leap_year and ref_month == 2: # febrero
            n_days += 1 # 28 --> 29

        date += datetime.timedelta(days=n_days)


    return date.strftime("%Y-%m-%d")


print(add_months("2022-12-30", "3"))

我还对变量名称进行了一些风格上的更改.这是一门艺术,而不是一门科学,命名变量,它总是归结为主观的意见,但请允许我谦虚地提出我的意见,更易读的名称.

还请注意,您有一条 comments ,大意是:

我需要ITER变量从1开始,而不是像ITER那样从0开始 Python中的变量

迭代变量starts where you tell it to start,给定您迭代的iterable.range(N)将是always start at zero,但它并不是必须的.您可以遍历[1, 2, 3],或者更好的是range(1, N + 1).

Note!

你的算法并没有完全按照人们的预期工作,人们自然会期望的输出是2023-03-30

不过,我会给你一个提示,想一想你需要添加到当前月份的which个月的天数……n_days = number_of_days_in_each_month[ref_month]……

Python相关问答推荐

如何合并具有相同元素的 torch 矩阵的行?

仅使用预先计算的排序获取排序元素

你能把函数的返回类型用作其他地方的类型吗?'

我可以不带视频系统的pygame,只用于游戏手柄输入吗?''

如何将一个文件的多列导入到Python中的同一数组中?

将数据从一个单元格保存到Jupyter笔记本中的下一个单元格

来自任务调度程序的作为系统的Python文件

合并Pandas中的数据帧,但处理不存在的列

简化通用属性的创建

给定y的误差时,线性回归系数的计算误差

有条件的滚动平均数(面试问题)

属性错误:';Styler';对象没有属性';样式';

盒子图分析

Df.Drop_Duplates(),以极点表示?

Python Pandas-如果满足多个条件,则将列表添加到数据框单元格

PANDA TO_DICT-按键列出行(_D)

在Numpy数组中的列子集上聚合

Python .删除DataFrame中的标题标签(&U;UNNAMED:0),并将其余标题标签向左移动(不更改值)

Lxml xPASS在XML中的第一个标记下面找不到标记

棋类游戏的极大极小函数