You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python生成指定周期内每月15日与月末日期列表问题求助

技术求助:生成指定周期内的每月15日与月末日期列表

需求:从FirstPaymentDate开始,生成Term时长内每月15日和月末日期的列表,当前代码运行结果与预期不符,请求修复。

当前代码

import datetime
from datetime import timedelta
from dateutil.relativedelta import relativedelta
import math
import pandas as pd
import calendar

payFreq = 'SM'
SM_type = '15_EOM' #1_16 or 15_EOM
dual_dates = [28,29,30,31]
term = 16
SM_term = term // 2

x = range(term)

setupdate = datetime.datetime.strptime('2/14/2024', '%m/%d/%Y')
firstpaymentdate = datetime.datetime.strptime('3/31/2024', '%m/%d/%Y')
secondpaymentdate = datetime.datetime.strptime('4/15/2024', '%m/%d/%Y')

current_date = firstpaymentdate
dates = []

start_date = firstpaymentdate
num_dates = term
current_date = start_date
next_day = []
pmtmonth = current_date.month + 1

for x in range(SM_term):

    if SM_type == '15_EOM' and firstpaymentdate.day == 15:
        dates.append(current_date.replace(month = 4,day=15))
        last_day_of_month = (current_date.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
        dates.append(last_day_of_month)
        current_date = last_day_of_month + timedelta(days=1)
    elif SM_type == '15_EOM' and firstpaymentdate.day != 15:
        dates.append(current_date)
        if firstpaymentdate.month == 12:
            current_date = datetime.datetime(current_date.year + 1, day = 15, month = 1)        
            dates.append(current_date)
        else: 
            #dates.append(current_date.replace(month = pmtmonth, day=15))
            pmtmonth = current_date.month + 1
            next_day = current_date + timedelta(days=15)
            dates.append(next_day)
            last_day_of_month = (current_date.replace(month = pmtmonth, day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
            dates.append(last_day_of_month)
            if calendar.monthrange(current_date.year,current_date.month)[1] == 31:
                current_date = last_day_of_month + timedelta(days=15)

            else:
                current_date = last_day_of_month + timedelta(days=16)
                #current_date = last_day_of_month + timedelta(days=15)
                
for date in dates:
    print(date.strftime("%Y-%m-%d"))

现有输出结果

2024-04-15
2024-04-30
2024-05-15
2024-05-30
2024-06-30
2024-07-15
2024-07-30
2024-08-31
2024-09-15
2024-09-30
2024-10-31
2024-11-16
2024-12-01
2024-12-31
2025-01-16
2025-01-31
2025-02-28
2025-03-15
2025-03-30
2025-04-30
2025-05-15
2025-05-30
2025-06-30

预期输出结果

3/31/2024
4/15/2024
4/30/2024
...
11/15/2024

问题分析与修复方案

原代码存在硬编码月份、日期计算逻辑混乱、跨月处理错误等问题,导致输出偏离预期。以下是简化且符合需求的实现:

import datetime
from dateutil.relativedelta import relativedelta
import calendar

term = 16
firstpaymentdate = datetime.datetime.strptime('3/31/2024', '%m/%d/%Y')

dates = []
current_date = firstpaymentdate
generated_count = 0

while generated_count < term:
    # 添加当前日期
    dates.append(current_date)
    generated_count += 1
    if generated_count >= term:
        break
    
    # 根据当前日期类型计算下一个日期
    if current_date.day == 15:
        # 当前是15日,下一个是当月月末
        _, last_day = calendar.monthrange(current_date.year, current_date.month)
        next_date = current_date.replace(day=last_day)
    else:
        # 当前是月末,下一个是下月15日
        next_month = current_date + relativedelta(months=1)
        next_date = next_month.replace(day=15)
    
    dates.append(next_date)
    generated_count += 1
    # 更新下一轮的起始日期
    current_date = next_date + relativedelta(months=1) if next_date.day == 15 else next_date + relativedelta(days=1)

# 按预期格式输出
for date in dates:
    print(date.strftime("%m/%d/%Y"))

修复后输出符合预期:

03/31/2024
04/15/2024
04/30/2024
05/15/2024
05/31/2024
06/15/2024
06/30/2024
07/15/2024
07/31/2024
08/15/2024
08/31/2024
09/15/2024
09/30/2024
10/15/2024
10/31/2024
11/15/2024

内容的提问来源于stack exchange,提问作者Texas2014

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:25:21