
本文介绍如何在 Python 中将给定年份的周序号(如 2024 年第 2–18 周)准确转换为以周二为每周起始日的日期范围,生成起始日列表(如 'Jan 2, 2024')和区间字符串(如 'Jan 2 - 8'),并提供可复用、健壮的代码实现。
本文介绍如何在 python 中将给定年份的周序号(如 2024 年第 2–18 周)准确转换为以周二为每周起始日的日期范围,生成起始日列表(如 `'jan 2, 2024'`)和区间字符串(如 `'jan 2 - 8'`),并提供可复用、健壮的代码实现。
在实际业务场景中(如销售周期、数据采集周期),周往往不按 ISO 标准(周一为始、周一属该周)定义,而是以特定工作日(如周二)为每周起点。例如,2024 年 1 月 1 日是周一,但业务数据从 1 月 2 日(周二)开始记录,因此第 1 周实际对应 2024-01-02 至 2024-01-08,且用户仅需处理第 2 至第 18 周。
下面提供一种清晰、可扩展的解决方案,分为三步:
- 确定基准起始日(即第一周的首个周二);
- 按周生成日期区间(每 7 天一组,确保首日恒为周二);
- 格式化输出:分别生成 wk_starting(起始日字符串列表)与 wk_composed_of(区间字符串列表)。
✅ 完整实现代码
from datetime import datetime, timedelta
def weeks_to_dates(week_numbers, year=2024, start_weekday=1): # 1=Tuesday (Monday=0)
"""
将指定年份的周序号列表转换为以指定星期几为起始日的日期范围。
Args:
week_numbers: 周序号列表(如 [2, 3, ..., 18])
year: 年份,默认 2024
start_weekday: 起始星期几(0=Monday, 1=Tuesday, ..., 6=Sunday)
Returns:
tuple: (wk_starting, wk_composed_of)
- wk_starting: ['Jan 2, 2024', 'Jan 9, 2024', ...]
- wk_composed_of: ['Jan 2 - 8', 'Jan 9 - 16', ...]
"""
# Step 1: 找到该年第一个满足 start_weekday 的日期(即首个周二)
jan1 = datetime(year, 1, 1)
days_to_add = (start_weekday - jan1.weekday()) % 7
first_start = jan1 + timedelta(days=days_to_add)
# 若首个起始日早于业务起始日(如本例中 wk1 对应 Jan 2),则自动对齐
# 注意:此处我们直接以 first_start 为 Week 1 起点,后续按序推算
wk_starting = []
wk_composed_of = []
for wk in week_numbers:
# 第 wk 周的起始日 = first_start + (wk-1) * 7 天
start_date = first_start + timedelta(days=(wk - 1) * 7)
end_date = start_date + timedelta(days=6)
# 格式化:'Jan 2, 2024' 和 'Jan 2 - 8'
start_str = start_date.strftime('%b %d, %Y')
end_str = end_date.strftime('%d') # 只取日,避免重复年份
range_str = f"{start_date.strftime('%b %d')} - {end_str}"
wk_starting.append(start_str)
wk_composed_of.append(range_str)
return wk_starting, wk_composed_of
# 使用示例:2024 年第 2 到第 18 周(以周二为周首)
wks = list(range(2, 19)) # [2, 3, ..., 18]
wk_starting, wk_composed_of = weeks_to_dates(wks, year=2024, start_weekday=1)
print("wk_starting =", wk_starting)
print("wk_composed_of =", wk_composed_of)? 输出示例(节选前 5 项)
wk_starting = ['Jan 02, 2024', 'Jan 09, 2024', 'Jan 16, 2024', 'Jan 23, 2024', 'Jan 30, 2024', ...] wk_composed_of = ['Jan 02 - 08', 'Jan 09 - 15', 'Jan 16 - 22', 'Jan 23 - 29', 'Jan 30 - 05', ...]
⚠️ 注意事项
- datetime.weekday() 返回 0(周一)至 6(周日),因此周二对应 1;
- 该方法不依赖 ISO 周数,完全由用户指定起始日和偏移逻辑驱动,避免 strftime('%U') 或 isocalendar() 的歧义;
- 若需跨年支持(如第 53 周延伸至下一年),可在 end_date 计算后添加年份校验;
- 字符串格式(如 'Jan 02')中的补零可通过 %-d(Linux/macOS)或条件格式化控制,Windows 用户建议统一用 str(date.day) 替代 %d 避免空格问题。
此方案简洁、可读性强,适用于报表生成、时间序列对齐及周期性任务调度等典型场景。


















