推荐用 calendar.monthcalendar() 逐周扫描计算工作日,因其返回周日开头的二维列表、天然适配“某月第几周”,再结合 calendar.weekday() 判断周一至周五(返回值0–4),并需额外处理法定节假日和调休日。

直接用 calendar.monthrange() 配合 calendar.weekday() 或 calendar.day_name 判断星期几,再排除周末——但别漏掉节假日,Python 标准库本身不处理法定节假日。
用 calendar.monthcalendar() 逐周扫描最稳妥
这个函数返回一个二维列表,每行是一周(周日开始),缺失日期用 0 表示。比手动算 weekday 更直观,也天然适配“某月第几周”的逻辑。
- 遍历
calendar.monthcalendar(year, month)的每一周 - 对每个非
0的日期,用calendar.weekday(year, month, day)判断是否为周一至周五(返回值 0–4) - 跳过
0和周六(5)、周日(6)
示例:计算 2024 年 10 月工作日天数
import calendar
year, month = 2024, 10
count = 0
for week in calendar.monthcalendar(year, month):
for day in week:
if day == 0:
continue
if calendar.weekday(year, month, day) < 5: # 0=Mon, 4=Fri
count += 1
print(count) # 输出 22注意 calendar.firstweekday() 的隐性影响
默认周起始是周一(calendar.MONDAY == 0),但如果你调过 calendar.setfirstweekday(calendar.SUNDAY),monthcalendar() 返回的结构不变(仍是周日开头),而 weekday() 返回值含义也不变(始终 Monday=0)。这点容易混淆。
立即学习“Python免费学习笔记(深入)”;
-
calendar.weekday()的返回值与firstweekday()设置无关,永远是 Monday=0 -
monthcalendar()的排列顺序固定为周日到周六,不受setfirstweekday()影响 - 所以判断工作日时,坚持用
< 5即可,不要试图对齐firstweekday()
法定节假日必须额外处理
calendar 模块只管星期,不管放假安排。比如 2024 年国庆节 10 月 1–7 日里,1–3 日是法定假日,4–7 日是调休上班日——模块无法识别。
- 简单项目可用硬编码字典,例如
holidays = {(2024, 10, 1), (2024, 10, 2), ...} - 生产环境建议用
holidays第三方包(支持多国/多年份),再和 weekday 结果取差集 - 特别注意调休日:得单独维护一个
work_on_weekend = {(2024, 10, 8), (2024, 10, 9)}这类集合
真正难的不是算周一到周五,而是确认哪几天“实际要上班”。calendar 模块只解决日历层面的结构问题,业务规则得自己兜底。


















