calendar模块 — 日历操作

Python标准库精讲专题 · 日期与时间篇 · 掌握日历操作工具

专题:Python标准库精讲系统学习

关键词:Python, 标准库, calendar, 日历, 月历, 年历, Calendar, TextCalendar, HTMLCalendar, isleap, weekday

一、calendar模块概述

Python的calendar模块是标准库中专门用于处理日历相关操作的工具模块。它提供了一系列函数和类,支持生成文本格式和HTML格式的日历、处理星期和月份信息、判断闰年、计算日期对应的星期等常见需求。calendar模块与datetime模块相辅相成:datetime专注于单个日期时间的精确计算和操作,而calendar则擅长宏观的日历展示和周期性日期计算。

calendar模块的核心设计围绕"日历"这一抽象概念展开,提供了一个基类Calendar和多个子类(TextCalendar、HTMLCalendar、LocalTextCalendar、LocaleHTMLCalendar),形成了清晰的类继承体系。开发者可以根据输出格式需求选择合适的子类,也可以继承Calendar类扩展自定义日历行为。

模块内置了两组重要常量:星期的英文名称列表(MONDAY到SUNDAY)和月份的英文名称列表(JANUARY到DECEMBER),便于国际化展示和日期计算中的引用。此外,calendar模块还提供了若干便捷的基础函数,无需实例化类即可直接调用,适合快速完成简单的日历操作。

import calendar # 查看日历模块的所有可用成员 print(dir(calendar)) # 输出中包含:Calendar, TextCalendar, HTMLCalendar, # isleap, leapdays, weekday, monthrange, # month_name, day_name, prcal, prmonth 等

二、基础函数 — 快速日历操作

calendar模块提供了多个可直接调用的基础函数,覆盖了日历生成、闰年判断、星期计算等常见场景。这些函数不需要创建任何对象即可使用,适合简单的脚本任务或快速原型开发。

2.1 文本月历与年历生成

month( year, month, w=2, l=1 )函数返回指定年月的文本月历字符串。参数w表示日期之间间隔的字符宽度,l表示每周之间间隔的行数。prmonth( year, month, w=2, l=1 )则直接打印结果,不返回字符串。

import calendar # 生成2026年5月的月历字符串 may_cal = calendar.month(2026, 5) print(may_cal) # 直接打印月历 calendar.prmonth(2026, 5) # 输出: # May 2026 # 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

calendar( year, w=2, l=1, c=6, m=3 )函数返回整年的年历字符串,参数c表示月份之间的水平间隔宽度,m表示每行显示的月份数。prcal( year, w=2, l=1, c=6, m=3 )则直接打印。

import calendar # 生成2026年的年历(每行3个月) year_cal = calendar.calendar(2026, c=3, m=3) print(year_cal) # 直接打印 calendar.prcal(2026)

2.2 闰年判断与相关计算

isleap( year )判断指定年份是否为闰年,返回布尔值。闰年的判断规则为:能被4整除但不能被100整除的年份,或者能被400整除的年份。leapdays( y1, y2 )返回y1年到y2年之间(包含y1,不包含y2)的闰年总数。

import calendar # 判断闰年 print(calendar.isleap(2024)) # True print(calendar.isleap(2025)) # False print(calendar.isleap(2026)) # False print(calendar.isleap(2000)) # True (能被400整除) print(calendar.isleap(1900)) # False (能被100整除但不能被400整除) # 计算闰年数量 print(calendar.leapdays(2000, 2026)) # 7个闰年

2.3 星期与月份信息计算

weekday( year, month, day )返回指定日期对应的星期索引,0表示星期一,6表示星期日。monthrange( year, month )返回一个元组 ( weekday_of_first_day, number_of_days_in_month ),即该月第一天的星期索引和该月的总天数。这两个函数是日常开发中最高频使用的基础工具。

import calendar # 计算某天是星期几 (0=星期一, 6=星期日) w = calendar.weekday(2026, 5, 5) print(w) # 1 — 星期二 print(calendar.day_name[w]) # Tuesday # 获取某月第一天是星期几和该月天数 first_weekday, days_in_month = calendar.monthrange(2026, 5) print(first_weekday) # 3 — 5月1日是星期四 print(days_in_month) # 31 — 5月有31天 # 简化:判断某日是否为周末 def is_weekend(y, m, d): w = calendar.weekday(y, m, d) return w >= 5 # 星期六=5, 星期日=6 print(is_weekend(2026, 5, 5)) # False (星期二) print(is_weekend(2026, 5, 9)) # True (星期六)

2.4 星期与月份名称常量

calendar模块提供了两组非常有用的常量列表。day_name和day_abbr分别存储星期全称和缩写(英文)。month_name和month_abbr分别存储月份全称和缩写(英文)。常量索引从0开始,其中month_name[0]和day_abbr[0]为空字符串,实际内容从索引1开始。

import calendar # 星期名称 print(list(calendar.day_name)) # ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] print(list(calendar.day_abbr)) # ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] # 月份名称 print(list(calendar.month_name)) # ['', 'January', 'February', 'March', 'April', 'May', 'June', # 'July', 'August', 'September', 'October', 'November', 'December'] print(list(calendar.month_abbr)) # ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', # 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] # 实际应用:将数字月份转为中文名称 month_num = 5 en_name = calendar.month_name[month_num] # 'May' print(f"{month_num}月对应的英文名称为:{en_name}")

2.5 其他实用函数

setfirstweekday( weekday )设置每周的第一天(默认是星期一)。firstweekday()返回当前设置的每周第一天。timegm( tuple )将struct_time元组转换为时间戳(秒数),与time.gmtime()功能互逆。

import calendar import time # 设置每周第一天为星期日 calendar.setfirstweekday(calendar.SUNDAY) print(calendar.firstweekday()) # 6 calendar.prmonth(2026, 5) # 星期日排在第一列 # 恢复为星期一 calendar.setfirstweekday(calendar.MONDAY) # timegm: 将时间元组转为时间戳 t = (2026, 5, 5, 12, 0, 0, 0, 0, 0) timestamp = calendar.timegm(t) print(timestamp) # 对应的UTC时间戳 print(time.gmtime(timestamp)) # 还原回struct_time

三、Calendar基类 — 日期迭代器

Calendar类是calendar模块的核心基类,它封装了日历数据生成的通用逻辑。Calendar类的构造函数接受可选参数firstweekday(整数0-6,默认0表示星期一),用于指定每周的第一天。Calendar本身不直接生成可视化的日历输出,而是作为数据迭代器提供各种日期集合,供其子类(TextCalendar、HTMLCalendar)渲染使用。

3.1 星期的迭代

iterweekdays()返回一个迭代器,按当前设置的每周第一天顺序迭代星期的索引值(0-6)。这个方法常用于生成日历表头。

import calendar cal = calendar.Calendar() # 默认星期一为每周第一天 for wd in cal.iterweekdays(): print(wd, calendar.day_name[wd]) # 输出: # 0 Monday # 1 Tuesday # 2 Wednesday # 3 Thursday # 4 Friday # 5 Saturday # 6 Sunday # 若设置星期日为每周第一天 cal_sun = calendar.Calendar(firstweekday=6) for wd in cal_sun.iterweekdays(): print(wd, calendar.day_name[wd]) # 输出: # 6 Sunday # 0 Monday # 1 Tuesday # 2 Wednesday # 3 Thursday # 4 Friday # 5 Saturday

3.2 日期的迭代方法

Calendar类提供了多种日期迭代方法,以不同的粒度遍历指定月份或年份的日期数据。

itermonthdates( year, month ):返回一个迭代器,遍历指定月份的所有日期,会向前后填充必要的前月/后月日期以补满整周(从周日或周一开始取决于设置),每个元素是一个datetime.date对象。

import calendar cal = calendar.Calendar() for d in cal.itermonthdates(2026, 5): print(d, end=' ') # 输出包含4月27日到5月31日的完整周期 # 因为5月1日是星期四,前4天(4月27-30日)会被包含进来

itermonthdays( year, month ):与itermonthdates类似,但返回的整数是月份中的日期号(1-31)。不在本月的日期用0表示。这种方法更适合纯数值计算。

import calendar cal = calendar.Calendar() for d in cal.itermonthdays(2026, 5): print(f'{d:2d}', end=' ') # 输出: 0 0 0 0 1 2 3 ... # 前4个0代表4月最后4天不在5月

itermonthdays2( year, month ):返回 ( 日期号, 星期索引 ) 元组的迭代器。不在本月的日期号为0。

import calendar cal = calendar.Calendar() for day_num, wd in cal.itermonthdays2(2026, 5): if day_num != 0: print(f'{day_num}日 = {calendar.day_name[wd]}') # 输出过滤掉不在5月份的所有日期

itermonthdays3( year, month ):返回 ( 年份, 月份, 日期号 ) 元组的迭代器。与itermonthdays2相比,多包含了年份和月份信息,便于处理跨月边缘的日期。

import calendar cal = calendar.Calendar() for y, m, d in cal.itermonthdays3(2026, 5): if d == 1: print(f'本月1日对应: {y}-{m}-{d}') break print(f'跨月日期: {y}-{m}-{d}') # 跨越到5月的日期会显示为 (2026, 5, 1) # 从4月跨越来的日期会显示为 (2026, 4, 27) 等

3.3 周列表与月列表方法

除了迭代器方法,Calendar还提供了返回列表的方法,将日期按周分组,结构更清晰。

monthdatescalendar( year, month ):返回一个列表,每个元素是一周的日期列表(datetime.date),不足整月的两侧用前后月日期补全。

import calendar cal = calendar.Calendar() weeks = cal.monthdatescalendar(2026, 5) for i, week in enumerate(weeks, 1): print(f'第{i}周:', week) # 输出5月的每一周,共6周

monthdayscalendar( year, month ):同上,但每个元素是日期号,非本月日期用0表示。

monthdays2calendar( year, month ):同上,但每个元素是 ( 日期号, 星期索引 ) 元组。

import calendar cal = calendar.Calendar() # monthdayscalendar for week in cal.monthdayscalendar(2026, 5): print(week) # monthdays2calendar for week in cal.monthdays2calendar(2026, 5): print(week) # 输出: # [(0, 0), (0, 0), (0, 0), (0, 0), (1, 3), (2, 4), (3, 5)] # [(4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5)] # ...

3.4 年列表方法

Calendar类还提供了按年组织数据的列表方法,适合生成全年日历数据。

yeardatescalendar( year, width=3 ):返回年历数据列表。width参数控制每行显示几个月。返回的三级嵌套列表结构为:[ 行列表 ],每行包含width个月,每月包含若干周,每周包含若干datetime.date对象。

yeardays2calendar( year, width=3 ):返回每月的 ( 日期号, 星期索引 ) 结构,日期号为0表示不属于本月。

import calendar cal = calendar.Calendar() # 每行显示3个月的全年日期数据 year_data = cal.yeardatescalendar(2026, width=3) # year_data[row_index][month_index][week_index][day_index] # 遍历第1行第1个月(1月)的所有周 for week in year_data[0][0]: for day in week: print(day, end=' ') print() # 输出1月份按周排列的日历数据

四、子类详解 — 多样化的日历输出

Calendar类提供了原始的日期数据迭代器,但实际生成可视化日历的任务由它的子类完成。TextCalendar生成格式化的文本日历,HTMLCalendar生成可用于网页的HTML日历代码。LocalTextCalendar和LocaleHTMLCalendar则支持本地化处理。

4.1 TextCalendar — 文本日历

TextCalendar继承自Calendar,覆写了formatmonth、formatyear等方法,生成对齐良好的纯文本日历字符串。它复用了父类的日期迭代逻辑,在此基础上添加了格式化和对齐代码。

import calendar # 创建文本日历对象 tc = calendar.TextCalendar() # 生成文本月历 month_str = tc.formatmonth(2026, 5) print(month_str) # May 2026 # 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 # 生成文本年历 year_str = tc.formatyear(2026, c=3, m=3) print(year_str) # 直接打印 tc.prmonth(2026, 5) tc.pryear(2026)

formatmonth方法返回的是字符串,prmonth直接打印;formatyear和pryear同理。TextCalendar的formatmonth实际上调用了父类的monthdatescalendar等技术方法来获取数据,然后渲染成文本格式。

4.2 HTMLCalendar — 网页日历

HTMLCalendar继承自Calendar,生成的是HTML表格格式的日历代码,可以直接嵌入网页中使用。它提供了formatmonth和formatyear等方法,返回包含table、tr、td等HTML标签的字符串。

import calendar hc = calendar.HTMLCalendar() # 生成HTML月历 html_month = hc.formatmonth(2026, 5) print(html_month) # 输出: # # # ... # ... # ... #
May 2026
MonTue
 
1
# 保存为HTML文件 with open('calendar_2026_05.html', 'w', encoding='utf-8') as f: f.write(f'{html_month}')

formatyear( year, width=3 )生成整年的HTML日历,每行显示width个月。

import calendar hc = calendar.HTMLCalendar() # 生成全年HTML日历 html_year = hc.formatyear(2026, width=3) # 自定义CSS类名 # HTMLCalendar生成的表格默认使用cssclasses类名 # 可以通过cssclasses属性自定义 hc.cssclasses = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] # 默认的cssclasses为: # ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] # 传入自定义CSS # 还可以设置cssclasses_month_head和cssclasses_year_head # 来控制月份标题的样式

CSS类名定制是HTMLCalendar的一个重要特性。默认的cssclasses为['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'],开发者可以替换为自己的类名,配合CSS实现个性化的日历样式。例如周末用不同颜色标记、当天高亮等效果。

4.3 本地化子类

LocalTextCalendar和LocaleHTMLCalendar是支持本地化的子类,它们继承自TextCalendar和HTMLCalendar,构造函数接受locale参数,用于指定区域代码,从而输出本地化语言的星期和月份名称。

import calendar import locale # 查看系统支持的locale # locale -a 在命令行查看所有可用locale # 创建中文本地化日历对象 try: # 尝试设置中文locale locale.setlocale(locale.LC_ALL, 'zh_CN.UTF-8') ltc = calendar.LocalTextCalendar(locale='zh_CN.UTF-8') ltc.prmonth(2026, 5) # 月份和星期名称将显示为中文 except locale.Error: print('当前系统不支持zh_CN.UTF-8 locale') # 创建其他语言本地化日历 # ltc_fr = calendar.LocalTextCalendar(locale='fr_FR.UTF-8') # ltc_de = calendar.LocalTextCalendar(locale='de_DE.UTF-8') # 使用本地化的HTMLCalendar try: lhc = calendar.LocaleHTMLCalendar(locale='zh_CN.UTF-8') html_month_cn = lhc.formatmonth(2026, 5) print(html_month_cn) except locale.Error: print('本地化HTMLCalendar创建失败') # 注:Windows系统上locale名称可能不同,如 'Chinese_China.936'

需要注意的是,本地化子类的有效性依赖于操作系统对指定locale的支持。在Windows和Linux系统上,locale名称格式可能不同。Windows通常使用类似'Chinese_China.936'的格式,而Linux使用'zh_CN.UTF-8'。

五、实战应用 — 日历模块的场景化实践

calendar模块在实际开发中有广泛的应用场景,从简单的日期计算到复杂的周期性事件管理。以下介绍几个典型的实战案例,展示如何将calendar模块的各种功能组合起来解决实际问题。

5.1 工作日计算器

使用calendar模块可以轻松实现指定月份的工作日计算功能。通过遍历月份的所有日期,排除周末(星期六和星期日),即可得到工作日列表。如果需要排除法定节假日,可以在基础逻辑上进一步过滤。

import calendar from datetime import date, timedelta def get_workdays(year, month, holidays=None): """获取指定月份的所有工作日(排除周末和可选节假日)""" holidays = holidays or [] cal = calendar.Calendar() workdays = [] for day_num, wd in cal.itermonthdays2(year, month): if day_num == 0: continue # 跳过不在本月的日期 if wd >= 5: continue # 跳过周末 d = date(year, month, day_num) if d in holidays: continue # 跳过节假日 workdays.append(d) return workdays # 示例:2026年5月的工作日 holidays_2026_05 = [ date(2026, 5, 1), # 劳动节 ] workdays = get_workdays(2026, 5, holidays_2026_05) print(f'2026年5月工作日共计:{len(workdays)}天') for d in workdays: print(d, calendar.day_name[d.weekday()]) # 计算工作日比例 total_days = calendar.monthrange(2026, 5)[1] print(f'工作日占比:{len(workdays)}/{total_days} = {len(workdays)/total_days*100:.1f}%')

5.2 会议日期生成器

在实际办公场景中,经常需要生成周期性会议的日期安排,比如"每月第二个星期二"开会。利用calendar模块的日期迭代功能,可以精准定位这类相对日期。

import calendar from datetime import date def nth_weekday(year, month, weekday, nth): """计算某月第n个指定星期几的日期 参数: weekday: 0=星期一 ... 6=星期日 nth: 1=第一个, 2=第二个, ... -1=最后一个 返回:date对象或None """ cal = calendar.Calendar() # 收集该月所有指定星期几的日期 matches = [] for day_num, wd in cal.itermonthdays2(year, month): if day_num != 0 and wd == weekday: matches.append(day_num) if not matches: return None if nth > 0 and nth <= len(matches): return date(year, month, matches[nth - 1]) elif nth == -1: return date(year, month, matches[-1]) return None # 示例:2026年5月第二个星期二 meeting_day = nth_weekday(2026, 5, 1, 2) # 1=Tuesday print(f'本月第二次周二例会日期:{meeting_day}') # 输出:2026-05-12 # 示例:每月最后一个星期五 last_friday = nth_weekday(2026, 5, 4, -1) # 4=Friday print(f'本月最后一个周五:{last_friday}') # 输出:2026-05-29 # 生成全年所有第二个星期三的会议日程 def generate_meeting_schedule(year, weekday, nth): meetings = [] for month in range(1, 13): d = nth_weekday(year, month, weekday, nth) if d: meetings.append(d) return meetings schedule = generate_meeting_schedule(2026, 2, 2) # 每月第二个周三 print('2026年所有第二个周三的会议日期:') for d in schedule: print(f' {d} — {calendar.day_name[d.weekday()]}')

5.3 日历Web组件

利用HTMLCalendar的定制能力,可以构建功能完整的Web日历组件。通过自定义CSS类名和添加额外处理逻辑,实现交互式日历。

import calendar from datetime import date class StyledHTMLCalendar(calendar.HTMLCalendar): """扩展HTMLCalendar,添加自定义样式处理""" def __init__(self, firstweekday=0): super().__init__(firstweekday) self.cssclasses = [ 'cal-mon', 'cal-tue', 'cal-wed', 'cal-thu', 'cal-fri', 'cal-sat', 'cal-sun' ] self.cssclasses_weekday_head = [ 'cal-head-mon', 'cal-head-tue', 'cal-head-wed', 'cal-head-thu', 'cal-head-fri', 'cal-head-sat', 'cal-head-sun' ] def formatday(self, day, weekday): """覆写单日格式化方法,支持高亮今天""" if day == 0: return ' ' today = date.today() css_class = self.cssclasses[weekday] # 高亮今天 if (self.year == today.year and self.month == today.month and day == today.day): css_class += ' today' # 周末特殊样式 if weekday >= 5: css_class += ' weekend' return f'{day}' def formatmonth(self, year, month): """覆写,保存年月信息供formatday使用""" self.year = year self.month = month return super().formatmonth(year, month) # 使用自定义日历 cal = StyledHTMLCalendar() html_output = cal.formatmonth(2026, 5) print(html_output) # 配套CSS示例(配合上述HTML使用): css_example = ''' .month { border-collapse: collapse; width: 100%; } .month th { background: #2c3e50; color: #fff; padding: 8px; } .cal-mon, .cal-tue, .cal-wed, .cal-thu, .cal-fri { padding: 8px; text-align: center; } .cal-sat, .cal-sun { padding: 8px; text-align: center; color: #e74c3c; } .today { background: #3498db; color: #fff; font-weight: bold; border-radius: 50%; } .weekend { background: #fdf0f0; } .noday { border: none; } '''

5.4 日期范围实用工具

结合calendar和datetime模块,可以构建实用的日期范围计算工具。

import calendar from datetime import date, timedelta def month_boundaries(year, month): """获取指定月份的第一天和最后一天""" first_day = date(year, month, 1) _, days_in_month = calendar.monthrange(year, month) last_day = date(year, month, days_in_month) return first_day, last_day def week_boundaries(year, month, day): """获取指定日期所在周的周一和周日""" wd = calendar.weekday(year, month, day) d = date(year, month, day) monday = d - timedelta(days=wd) sunday = monday + timedelta(days=6) return monday, sunday def quarter_months(year, quarter): """获取指定季度的3个月份""" months = [(quarter - 1) * 3 + i + 1 for i in range(3)] result = [] for m in months: first, last = month_boundaries(year, m) result.append((m, first, last)) return result # 示例 first, last = month_boundaries(2026, 5) print(f'2026年5月范围:{first} ~ {last}') mon, sun = week_boundaries(2026, 5, 15) print(f'2026年5月15日所在周:{mon} ~ {sun}') q2 = quarter_months(2026, 2) print('2026年第二季度:') for m, f, l in q2: print(f' {calendar.month_name[m]}: {f} ~ {l}')

5.5 年龄与生日计算

日历模块还常用于涉及月份的计算,如精确年龄计算。结合datetime可以获得比单纯日期加减更准确的结果。

import calendar from datetime import date def calculate_age(birth_date, target_date=None): """计算到目标日期的精确年龄(周岁)""" if target_date is None: target_date = date.today() age = target_date.year - birth_date.year # 检查是否已过生日 if (target_date.month, target_date.day) < (birth_date.month, birth_date.day): age -= 1 # 返回年龄和剩余天数 next_birthday_year = target_date.year + (1 if age == 0 else 0) # 考虑闰年2月29日情况 if birth_date.month == 2 and birth_date.day == 29: if not calendar.isleap(next_birthday_year): next_birthday = date(next_birthday_year, 3, 1) else: next_birthday = date(next_birthday_year, 2, 29) else: next_birthday = date(next_birthday_year, birth_date.month, birth_date.day) days_until_birthday = (next_birthday - target_date).days return age, days_until_birthday # 示例 birth = date(1990, 7, 15) today = date(2026, 5, 5) age, days_left = calculate_age(birth, today) print(f'出生日期:{birth}') print(f'当前年龄:{age}周岁') print(f'距离下次生日还有:{days_left}天')

六、核心总结

calendar模块是Python标准库中日历操作的核心模块,它通过清晰的类层次结构和丰富的工具函数,为开发者提供了一套完整的日历数据处理方案。以下是对本专题核心知识点的系统总结。

1. 模块定位:calendar与datetime、time共同构成Python的日期时间工具体系。calendar负责宏观的日历展示和日期周期性计算,datetime专注于精确的日期时间对象操作,time提供底层时间戳和系统时间接口。三者各司其职,在复杂应用场景中经常配合使用。

2. 基础函数速查:month()/prmonth()生成单月文本月历,calendar()/prcal()生成全年文本年历,isleap()判断闰年,leapdays()计算年份区间内的闰年数,weekday()计算星期索引,monthrange()返回当月第一天星期和总天数,day_name/month_name提供星期和月份的名称常量。

3. 类继承体系:Calendar(基类,提供日期迭代器)→ TextCalendar(文本日历输出)和HTMLCalendar(HTML日历输出),以及面向本地化的LocalTextCalendar和LocaleHTMLCalendar。基类负责数据生成逻辑,子类负责格式化和渲染,体现了清晰的单一职责和模板方法设计模式。

4. 核心迭代方法:itermonthdates返回datetime.date对象,itermonthdays返回日期号(0表示跨月),itermonthdays2返回(日期号, 星期)元组,itermonthdays3返回(年, 月, 日)元组。对应的列表方法monthdatescalendar、monthdayscalendar、monthdays2calendar按周分组返回列表,便于层级遍历。

5. 实战模式:工作日计算(itermonthdays2 + 周末过滤)、周期性会议日期生成(Calendar迭代 + nth过滤)、HTML日历Web组件(继承HTMLCalendar覆写formatday)、日期范围边界计算(monthrange + datetime)。这些模式覆盖了从数据分析到Web开发的主要应用场景。

6. 扩展方向:实际项目中的日历需求往往超出标准库的能力范围。对于复杂的时区转换和精确时间计算,建议使用pytz或zoneinfo模块。对于业务日历(如交易日历、排班日历),通常需要基于Calendar类自定义子类。对于前端交互式日历组件(如日期选择器、事件日历),建议在前端使用专门的JavaScript日历库,后端仅提供数据API接口。

学习建议:calendar模块的函数接口简单易用,适合快速上手;类体系则提供了高度可扩展的架构。日常开发中,最常用的功能是isleap、weekday、monthrange三个基础函数,以及TextCalendar.formatmonth的文本生成能力。深入学习时应重点理解Calendar的迭代器设计思想——它将"数据生成"与"格式渲染"分离,这种设计模式在Python标准库中多处可见(如csv模块的reader/writer分离)。