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

如何将YYYY-MM-DD格式的日期列表转换为「17-19, 23 APR 2021」样式的字符串?

简洁实现思路:用分组工具高效合并连续日期

你的核心痛点是连续天数的合并逻辑,其实借助itertools.groupby可以非常优雅地解决这个问题,同时我们还能简化日期分组的逻辑,避免多层字典的繁琐。下面是完全贴合你需求的实现方案:

import datetime
from itertools import groupby

dates = [ "2021-04-17", "2021-04-18", "2021-04-19", "2021-04-23", "2021-04-17", "2022-05-02", "2022-05-04" ]

# 1. 解析日期并按「年-月」分组,自动去重+排序天数
date_groups = {}
for date_str in dates:
    dt = datetime.datetime.strptime(date_str, "%Y-%m-%d")
    group_key = (dt.year, dt.month)
    # 用集合自动去重,后续转成排序后的列表(合并连续日期必须依赖有序性)
    date_groups.setdefault(group_key, set()).add(dt.day)
for key in date_groups:
    date_groups[key] = sorted(date_groups[key])

# 2. 定义连续天数合并函数
def merge_days(days_list):
    merged_segments = []
    # 核心逻辑:用「天数 - 索引」的差值分组,连续天数的差值会完全相同
    for _, consecutive_group in groupby(enumerate(days_list), lambda x: x[1] - x[0]):
        group_items = list(consecutive_group)
        if len(group_items) == 1:
            merged_segments.append(str(group_items[0][1]))
        else:
            merged_segments.append(f"{group_items[0][1]}-{group_items[-1][1]}")
    return ", ".join(merged_segments)

# 3. 格式化输出每个年月组的结果
for (year, month), days in date_groups.items():
    month_abbr = datetime.datetime(year, month, 1).strftime("%b").upper()
    final_str = f"{merge_days(days)} {month_abbr} {year}"
    print(final_str)

关键细节说明:

  • 日期分组优化:用(年,月)作为字典键替代多层嵌套,逻辑更直观;用集合存储天数自动处理重复项,最后排序保证连续天数相邻,这是合并逻辑的基础。
  • 连续天数合并:itertools.groupby通过「天数与索引的差值」来识别连续序列——比如17、18、19对应的索引是0、1、2,17-0=17、18-1=17、19-2=17,差值相同则判定为连续组,完美解决你的合并需求。
  • 格式适配:用strftime("%b")获取月份英文缩写,转大写后和合并后的天数字符串、年份组合成你要的格式。

运行结果:

17-19, 23 APR 2021
2, 4 MAY 2022

这个方案既满足了去重、无序日期、跨年月处理等所有约束,又把核心逻辑简化到了最紧凑的程度,比你之前的多层字典写法更易读和维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:12:32