Python - 生成每月15号和最后一天的日期列表

0 投票
2 回答
63 浏览
提问于 2025-04-14 17:23

我正在尝试生成一个日期列表,这些日期是每个月的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

任何帮助都非常感谢!

2 个回答

0

你把事情想得太复杂了。如果你只想要每个月的15号或者月底的日期,那就写一个函数来专门生成这些日期。然后你可以多次使用这个函数。

def fifteenth_or_EOM(dt):
    if dt.day == 15 or dt.month != (dt+datetime.timedelta(days=1)).month:
        # it was already the 15th or the end of the month
        return dt
    if dt.day < 15:
        dt = dt.replace(day=1) - datetime.timedelta(days=1)
    else:
        dt = dt.replace(day=15)
    return dt

firstpaymentdate = datetime.datetime.strptime('3/31/2024', '%m/%d/%Y')
current_date = firstpaymentdate
dates = []

term = 16
half_month = datetime.timedelta(days=16)
for x in range(term):
    dates.append(current_date)
    current_date = fifteenth_or_EOM(current_date + half_month)

for date in dates:
    print(date.strftime("%Y-%m-%d"))

2024-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
0

这是我对这个问题的解决方案的尝试。我省略了一些与这个问题无关的导入和变量。

from datetime import date, datetime, timedelta


def get_days_in_month(year, month):
    return (
        (date(year, month, 1) + timedelta(days=31)).replace(day=1)
        - date(year, month, 1)
    ).days


if __name__ == "__main__":
    SM_type = "15_EOM"  # 1_16 or 15_EOM
    term = 16

    firstpaymentdate = datetime.strptime("3/31/2024", "%m/%d/%Y")
    dates = [firstpaymentdate]

    current_date = firstpaymentdate
    if SM_type == "15_EOM":
        for _ in range(term - 1):
            if current_date.day == 15:
                num_days = get_days_in_month(current_date.year, current_date.month)
                current_date = date(current_date.year, current_date.month, num_days)
            else:
                current_date = current_date + timedelta(15)

            dates.append(current_date)

    for d in dates:
        print(d.strftime("%Y-%m-%d"))

撰写回答