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

如何按指定间隔拆分两个YYYYmm格式日期区间的月份?

日期区间按指定月数拆分的解决方案

问题描述

我有两个YYYYmm格式的日期:start为202307,end为202612。希望按照指定间隔拆分该日期区间,例如调用split_months('202307','202405',5)时,期望返回结果(('202307','202311'), ('202312','202404'), ('202405','202405'))。我尝试了以下代码但逻辑存在问题,请求相关解决建议:

def split_months(start, end, intv):
    from datetime import datetime
    periodList = []
    periodRangeSplitList = []

    start = datetime.strptime(start ,"%Y%m")
    end = datetime.strptime(end ,"%Y%m")
    mthDiff = relativedelta.relativedelta(end, start)

    if mthDiff == 0:
        periodRangeSplitList.append((start,start))
        return periodRangeSplitList

    diff = mthDiff / intv
    print(diff)

    for i in range(intv):
        periodList.append ((start + diff * i).strftime("%Y%m"))
    periodList.append(end.strftime("%Y%m"))
    print(periodList)

问题分析

原代码存在以下核心问题:

  • 直接对relativedelta对象做除法运算会导致精度偏差,无法精准计算区间起止日期
  • 循环仅生成零散日期点,未组装成要求的区间元组格式
  • 未处理最后一个区间不足指定间隔的边界情况

解决方案

以下是修正后的代码,核心思路是先计算总月数差,再逐个生成每个区间的起止日期:

from datetime import datetime
from dateutil.relativedelta import relativedelta

def split_months(start_str, end_str, intv):
    # 转换为datetime对象,方便日期运算
    start = datetime.strptime(start_str, "%Y%m")
    end = datetime.strptime(end_str, "%Y%m")
    
    # 计算两个日期之间的总月数差
    total_months = (end.year - start.year) * 12 + (end.month - start.month)
    result = []
    
    # 处理起止日期相同的特殊情况
    if total_months == 0:
        return ((start_str, end_str),)
    
    current_start = start
    while current_start <= end:
        # 计算当前区间的结束日期:起始日期 + 间隔月数 -1
        current_end = current_start + relativedelta(months=intv - 1)
        # 如果计算出的结束日期超过最终终点,就用最终日期作为区间结束
        if current_end > end:
            current_end = end
        # 转换为YYYYmm格式的字符串
        start_formatted = current_start.strftime("%Y%m")
        end_formatted = current_end.strftime("%Y%m")
        result.append((start_formatted, end_formatted))
        # 更新下一个区间的起始日期:当前结束日期 +1个月
        current_start = current_end + relativedelta(months=1)
    
    return tuple(result)

代码说明

  1. 日期转换:将输入的字符串日期转为datetime对象,便于后续的月份加减运算
  2. 总月数计算:通过年份差和月份差计算总月数,避免relativedelta直接运算的精度问题
  3. 区间生成逻辑:
    • 从起始日期开始,每次生成一个长度为intv个月的区间(最后一个区间可能不足)
    • 若当前计算的结束日期超出最终终点,则以最终日期作为该区间的结束
    • 将每个区间的起止日期转为指定格式后加入结果列表
  4. 结果返回:将结果列表转为元组,匹配示例中的返回格式要求

测试示例

调用split_months('202307','202405',5),返回结果为:

(('202307', '202311'), ('202312', '202404'), ('202405', '202405'))

与期望完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:05:27