下面我将从基础到进阶,详细介绍如何使用 calendar 模块进行计算。

模块简介
你需要导入 calendar 模块:
import calendar
基础功能:生成日历
这是 calendar 模块最直观的用途。
1 打印整年日历
使用 calendar(year) 函数可以直接打印指定年份的日历。
# 打印 2025 年的整年日历 calendar.pcal(2025) # pcal 是 pretty_calendar 的缩写,但更常用的是 calendar(2025) print(calendar.calendar(2025))
输出会是一个格式化良好的文本日历,每个月份占据三行。

2 打印单月日历
使用 monthcalendar(year, month) 或 month(year, month)。
calendar.month(year, month): 返回一个格式化的单月字符串。calendar.monthcalendar(year, month): 返回一个表示该月的周列表(一个二维列表),其中每周是一个子列表,如果某个月的某一天不属于该月(如下个月的1号或上个月的最后几天),则用0表示。
示例:
# 打印 2025 年 10 月的日历(格式化字符串) print(calendar.month(2025, 10))
输出:
October 2025
Mo Tu We Th Fr Sa Su
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
示例:使用 monthcalendar

# 获取 2025 年 10 月的周数据 october_2025 = calendar.monthcalendar(2025, 10) print(october_2025)
输出:
[[0, 0, 0, 0, 0, 1, 2], # 第一周,前5天是0
[3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16],
[17, 18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29, 30],
[31, 0, 0, 0, 0, 0, 0]] # 最后一周,后6天是0
核心计算功能
这才是“计算”的关键所在。
1 获取某一天是星期几
calendar.weekday(year, month, day) 函数返回一个整数,代表星期几(周一为 0,周日为 6)。
# 查询 2025年10月1日 是星期几
weekday_num = calendar.weekday(2025, 10, 1)
print(f"2025年10月1日是星期几(数字表示): {weekday_num}") # 输出: 6 (周日)
# 将数字转换为星期名称
weekday_name = calendar.day_name[weekday_num]
print(f"2025年10月1日是星期: {weekday_name}") # 输出: Sunday
2 获取某月有多少天
calendar.monthrange(year, month) 返回一个元组 (first_weekday, num_days)。
first_weekday: 该月第一天是星期几(周一为0,周日为6)。num_days: 该月的总天数。
# 查询 2025年2月 的第一天是星期几,以及总天数
first_day, num_days = calendar.monthrange(2025, 2)
print(f"2025年2月第一天是星期几(数字): {first_day}") # 输出: 2 (周三)
print(f"2025年2月总天数: {num_days}") # 输出: 28
3 判断闰年
calendar.isleap(year) 函数返回 True(如果是闰年)或 False(如果不是闰年)。
# 判断 2025 年和 2025 年是否是闰年
print(f"2025年是闰年吗? {calendar.isleap(2025)}") # 输出: True
print(f"2025年是闰年吗? {calendar.isleap(2025)}") # 输出: False
高级计算与应用
1 计算一个月中的所有周一(或特定工作日)
结合 monthcalendar,我们可以轻松找出某个特定工作日的所有日期。
def find_all_mondays(year, month):
"""
找出指定年月中的所有星期一的日期。
"""
# 获取该月的周数据
month_cal = calendar.monthcalendar(year, month)
mondays = []
# calendar.MONDAY 是一个常量,值为 0
for week in month_cal:
if week[calendar.MONDAY] != 0: # 确保不是跨月的0
mondays.append(week[calendar.MONDAY])
return mondays
# 找出 2025年10月 的所有星期一
mondays_in_oct = find_all_mondays(2025, 10)
print(f"2025年10月的所有星期一: {mondays_in_oct}") # 输出: [2, 9, 16, 23, 30]
2 计算两个日期之间的工作日数
这是一个非常实用的计算,比如计算项目工期或员工出勤天数。
import datetime
def count_workdays(start_date, end_date):
"""
计算两个日期之间的工作日数(周一至周五)。
"""
# 确保是 datetime 对象
if not isinstance(start_date, datetime.date):
start_date = datetime.datetime.strptime(start_date, "%Y-%m-%d").date()
if not isinstance(end_date, datetime.date):
end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d").date()
delta = end_date - start_date
workdays = 0
for i in range(delta.days + 1):
current_day = start_date + datetime.timedelta(days=i)
# 检查是否是周一到周五 (weekday()返回0-6, 0是周一)
if current_day.weekday() < 5:
workdays += 1
return workdays
# 计算从 2025-10-01 到 2025-10-31 的工作日数
start = datetime.date(2025, 10, 1)
end = datetime.date(2025, 10, 31)
print(f"从 {start} 到 {end} 的工作日数是: {count_workdays(start, end)}") # 输出: 23
3 计算月份的第n个工作日
计算某月的第一个周五是几号。
def find_nth_weekday(year, month, weekday, n):
"""
找出指定年月的第 n 个星期几。
weekday: 0 (周一) 到 6 (周日)
n: 第几个,从1开始
"""
# 获取该月的周数据
month_cal = calendar.monthcalendar(year, month)
# 遍历每一周
for week in month_cal:
day = week[weekday]
if day != 0: # 找到第一个非0的对应星期几
n -= 1
if n == 0:
return day
return None # 如果找不到(比如n太大)
# 找出 2025年10月 的第3个周五 (weekday=4)
third_friday = find_nth_weekday(2025, 10, calendar.FRIDAY, 3)
print(f"2025年10月的第3个周五是: {third_friday}") # 输出: 20
常用常量
calendar 模块还提供了一些方便的常量:
calendar.MONDAY,calendar.TUESDAY, ...,calendar.SUNDAY: 值为 0 到 6。calendar.JANUARY,calendar.FEBRUARY, ...,calendar.DECEMBER: 值为 1 到 12。calendar.day_name: 一个列表,包含星期名称的完整拼写(如 "Monday")。calendar.day_abbr: 一个列表,包含星期名称的缩写(如 "Mon")。calendar.month_name: 一个列表,包含月份名称的完整拼写(如 "January"),注意第一个元素是空字符串。calendar.month_abbr: 一个列表,包含月份名称的缩写(如 "Jan")。
| 功能 | 函数/方法 | 描述 |
|---|---|---|
| 生成日历 | calendar(year) |
打印整年日历 |
calendar.month(year, month) |
打印单月日历(格式化字符串) | |
calendar.monthcalendar(year, month) |
返回单月的周数据(二维列表) | |
| 核心计算 | calendar.weekday(year, month, day) |
返回某天是星期几(0-6) |
calendar.monthrange(year, month) |
返回 (该月第一天星期几, 该月总天数) | |
calendar.isleap(year) |
判断是否是闰年,返回布尔值 | |
| 高级应用 | 结合 monthcalendar 和循环 |
计算特定工作日的所有日期 |
结合 datetime 和循环 |
计算两个日期之间的工作日数 | |
结合 monthcalendar 和循环 |
计算月份的第n个工作日 | |
| 常量 | calendar.MONDAY, calendar.day_name 等 |
提供星期、月份的名称和数字映射 |
掌握这些函数和思路,你就可以用 Python 的 calendar 模块轻松解决绝大多数与日期和日历相关的计算问题。
