Python calendar 教程
calendar 模块提供了与日历相关的功能,包括生成日历、计算日期、判断闰年等。
基本功能
1. 判断闰年
import calendar# 判断是否为闰年
years = [2000, 2020, 2023, 2024, 2100]for year in years:is_leap = calendar.isleap(year)print(f"{year}年是{'闰年' if is_leap else '平年'}")
输出:text2000年是闰年
2020年是闰年
2023年是平年
2024年是闰年
2100年是平年
2. 获取两个年份之间的闰年数量
import calendar# 计算两个年份之间的闰年数量
start_year = 2000
end_year = 2030
leap_count = calendar.leapdays(start_year, end_year)
print(f"{start_year}年到{end_year}年之间有{leap_count}个闰年")
3. 获取月份信息
import calendar# 获取月份的天数范围
year, month = 2023, 2
month_range = calendar.monthrange(year, month)
print(f"{year}年{month}月: 第一天是星期{month_range[0]}, 共有{month_range[1]}天")# 获取月份天数(更简单的方法)
days_in_month = calendar.monthlen(year, month) # Python 3.7+
print(f"{year}年{month}月有{days_in_month}天")
4. 星期相关函数
import calendar# 获取星期的名称
print("星期名称:")
for i in range(7):print(f"{i}: {calendar.day_name[i]}")print("\n星期缩写:")
for i in range(7):print(f"{i}: {calendar.day_abbr[i]}")# 设置一周的第一天(默认0=周一)
calendar.setfirstweekday(calendar.SUNDAY) # 设置周日为一周的第一天
print(f"\n一周的第一天: {calendar.firstweekday()}") # 6# 恢复默认(周一为一周的第一天)
calendar.setfirstweekday(0)
日历生成
1. 月份日历
import calendar# 生成一个月的日历矩阵
year, month = 2023, 10
month_calendar = calendar.monthcalendar(year, month)
print(f"{year}年{month}月的日历矩阵:")
for week in month_calendar:print(week)
输出:text2023年10月的日历矩阵:
[0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0]
2. 年份日历
import calendar# 生成整年的日历矩阵
year = 2023
year_calendar = calendar.calendar(year)
print(f"{year}年的日历:")
print(year_calendar)
文本日历
1. 月份文本日历
import calendaryear, month = 2023, 12# 生成纯文本月份日历
text_calendar = calendar.month(year, month)
print(f"{year}年{month}月日历:")
print(text_calendar)# 自定义宽度和长度
custom_calendar = calendar.month(year, month, w=4, l=2)
print("自定义格式:")
print(custom_calendar)
输出:text2023年12月日历:December 2023
Mo Tu We Th Fr Sa Su1 2 34 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
2. 年份文本日历
import calendaryear = 2023# 生成整年文本日历
year_text = calendar.calendar(year)
print(f"{year}年日历:")
print(year_text)# 自定义参数:列宽、行间距、列间距
custom_year = calendar.calendar(year, w=3, l=1, c=6)
print("自定义格式的年份日历:")
print(custom_year)
3. 月份名称和缩写
import calendar# 获取月份名称
print("月份全称:")
for i in range(1, 13):print(f"{i}: {calendar.month_name[i]}")print("\n月份缩写:")
for i in range(1, 13):print(f"{i}: {calendar.month_abbr[i]}")# 获取特定月份名称
month_name = calendar.month_name[10]
month_abbr = calendar.month_abbr[10]
print(f"\n第10个月: {month_name} ({month_abbr})")
HTML 日历
1. 月份 HTML 日历
import calendaryear, month = 2023, 12# 生成月份HTML日历
html_calendar = calendar.HTMLCalendar()
month_html = html_calendar.formatmonth(year, month)
print(f"{year}年{month}月HTML日历:")
print(month_html)# 带CSS样式的HTML日历
month_html_with_css = html_calendar.formatmonth(year, month, withyear=True)
print("带年份的HTML日历:")
print(month_html_with_css)
2. 年份 HTML 日历
import calendaryear = 2023# 生成整年HTML日历
html_calendar = calendar.HTMLCalendar()
year_html = html_calendar.formatyear(year, width=3)
print(f"{year}年HTML日历:")
print(year_html)# 自定义CSS类
year_html_custom = html_calendar.formatyear(year, width=4, css='calendar.css')
print("带自定义CSS的年份日历:")
print(year_html_custom)
3. 自定义 HTML 日历样式
import calendarclass CustomHTMLCalendar(calendar.HTMLCalendar):# 重写CSS类cssclasses = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]# 重写CSS类属性cssclass_month_head = "month-head"cssclass_month = "month"cssclass_year = "year"cssclass_year_head = "year-head"def formatday(self, day, weekday):"""自定义日期单元格格式"""if day == 0:return '<td class="noday"> </td>' # 空白单元格else:# 周末特殊样式if weekday == 5 or weekday == 6: # 周六或周日return f'<td class="weekend">{day}</td>'else:return f'<td class="day">{day}</td>'# 使用自定义HTML日历
custom_cal = CustomHTMLCalendar()
html_output = custom_cal.formatmonth(2023, 12)
print("自定义HTML日历:")
print(html_output)
日期计算
1. 星期相关计算
import calendar
from datetime import datedef get_weekday_info(year, month, day):"""获取日期相关的星期信息"""d = date(year, month, day)# 星期几(0=周一, 6=周日)weekday_num = d.weekday()# 星期名称weekday_name = calendar.day_name[weekday_num]# 一年中的第几周week_number = d.isocalendar()[1]return {'date': d,'weekday_number': weekday_num,'weekday_name': weekday_name,'week_number': week_number}# 使用示例
info = get_weekday_info(2023, 12, 25)
print(f"日期: {info['date']}")
print(f"星期数字: {info['weekday_number']}")
print(f"星期名称: {info['weekday_name']}")
print(f"一年中的第几周: {info['week_number']}")
2. 月份边界计算
import calendar
from datetime import date, timedeltadef get_month_boundaries(year, month):"""获取月份的开始和结束日期"""# 月份第一天first_day = date(year, month, 1)# 月份最后一天_, last_day_num = calendar.monthrange(year, month)last_day = date(year, month, last_day_num)# 月份第一天是星期几first_weekday = first_day.weekday()return {'first_day': first_day,'last_day': last_day,'first_weekday': first_weekday,'days_in_month': last_day_num}# 使用示例
bounds = get_month_boundaries(2023, 2)
print(f"月份开始: {bounds['first_day']}")
print(f"月份结束: {bounds['last_day']}")
print(f"第一天是星期: {bounds['first_weekday']}")
print(f"月份天数: {bounds['days_in_month']}")
实际应用示例
1. 工作日计算器
import calendar
from datetime import date, timedeltadef count_workdays(start_date, end_date):"""计算两个日期之间的工作日数量"""total_days = (end_date - start_date).days + 1workdays = 0for day in range(total_days):current_date = start_date + timedelta(days=day)# 周一至周五为工作日if current_date.weekday() < 5:workdays += 1return workdays# 使用示例
start = date(2023, 12, 1)
end = date(2023, 12, 31)
workday_count = count_workdays(start, end)
print(f"{start} 到 {end} 之间有 {workday_count} 个工作日")
2. 节假日日历生成器
import calendar
from datetime import dateclass HolidayCalendar:def __init__(self, year):self.year = yearself.holidays = self._get_holidays()def _get_holidays(self):"""定义节假日(示例)"""holidays = {# 元旦date(self.year, 1, 1): "元旦",# 春节(简化示例)date(self.year, 1, 22): "春节",date(self.year, 1, 23): "春节",date(self.year, 1, 24): "春节",# 劳动节date(self.year, 5, 1): "劳动节",# 国庆节date(self.year, 10, 1): "国庆节",date(self.year, 10, 2): "国庆节",date(self.year, 10, 3): "国庆节",}return holidaysdef print_calendar_with_holidays(self):"""打印带节假日的日历"""cal = calendar.TextCalendar()for month in range(1, 13):print(f"\n{self.year}年{month}月")print("一 二 三 四 五 六 日")month_days = cal.monthdayscalendar(self.year, month)for week in month_days:week_str = ""for day in week:if day == 0:week_str += " "else:current_date = date(self.year, month, day)if current_date in self.holidays:week_str += f"*{day:2}"else:week_str += f"{day:2} "print(week_str)# 使用示例
holiday_cal = HolidayCalendar(2023)
holiday_cal.print_calendar_with_holidays()
3. 会议日程安排
import calendar
from datetime import date, timedeltadef generate_meeting_schedule(year, month, weekday, week_number=None):"""生成会议日程"""meetings = []cal = calendar.Calendar()for week in cal.monthdatescalendar(year, month):meeting_day = week[weekday] # weekday: 0=周一, 6=周日# 确保日期在指定月份内if meeting_day.month == month:if week_number is None or week[weekday].isocalendar()[1] == week_number:meetings.append(meeting_day)return meetings# 使用示例
# 生成12月所有周一的会议
monday_meetings = generate_meeting_schedule(2023, 12, 0)
print("12月周一会议日程:")
for meeting in monday_meetings:print(meeting.strftime("%Y-%m-%d (%A)"))# 生成每月第二周的周三会议
wednesday_meetings = generate_meeting_schedule(2023, 12, 2, week_number=2)
print("\n12月第二周周三会议:")
for meeting in wednesday_meetings:print(meeting.strftime("%Y-%m-%d"))
4. 生日提醒系统
import calendar
from datetime import date, timedeltaclass BirthdayReminder:def __init__(self):self.birthdays = {}def add_birthday(self, name, birth_date):"""添加生日"""self.birthdays[name] = birth_datedef get_upcoming_birthdays(self, days=30):"""获取未来几天内的生日"""today = date.today()end_date = today + timedelta(days=days)upcoming = []for name, birth_date in self.birthdays.items():# 计算今年的生日this_year_birthday = date(today.year, birth_date.month, birth_date.day)# 如果今年的生日已经过了,计算明年的生日if this_year_birthday < today:this_year_birthday = date(today.year + 1, birth_date.month, birth_date.day)# 检查是否在指定天数内if today <= this_year_birthday <= end_date:days_until = (this_year_birthday - today).daysupcoming.append({'name': name,'birthday': this_year_birthday,'days_until': days_until,'age': this_year_birthday.year - birth_date.year})# 按日期排序upcoming.sort(key=lambda x: x['birthday'])return upcoming# 使用示例
reminder = BirthdayReminder()
reminder.add_birthday("张三", date(1990, 12, 20))
reminder.add_birthday("李四", date(1985, 12, 25))
reminder.add_birthday("王五", date(1995, 1, 15))upcoming = reminder.get_upcoming_birthdays(60)
print("即将到来的生日:")
for birthday in upcoming:print(f"{birthday['name']}: {birthday['birthday']} (还有{birthday['days_until']}天, 满{birthday['age']}岁)")
5. 项目进度日历
import calendar
from datetime import date, timedeltaclass ProjectCalendar:def __init__(self, project_name, start_date, end_date):self.project_name = project_nameself.start_date = start_dateself.end_date = end_dateself.milestones = []def add_milestone(self, name, milestone_date):"""添加里程碑"""self.milestones.append({'name': name,'date': milestone_date})def generate_project_calendar(self):"""生成项目进度日历"""# 计算项目总天数total_days = (self.end_date - self.start_date).days + 1# 创建日历cal = calendar.TextCalendar()current_date = self.start_datewhile current_date <= self.end_date:year, month = current_date.year, current_date.monthprint(f"\n{year}年{month}月 - 项目进度")month_cal = cal.monthdayscalendar(year, month)for week in month_cal:week_display = ""for day in week:if day == 0:week_display += " "else:current_day = date(year, month, day)if current_day < self.start_date or current_day > self.end_date:week_display += " "else:# 检查是否是里程碑is_milestone = any(milestone['date'] == current_day for milestone in self.milestones)if is_milestone:week_display += f"*{day:2}"else:week_display += f"{day:2} "print(week_display)# 移动到下个月if month == 12:current_date = date(year + 1, 1, 1)else:current_date = date(year, month + 1, 1)# 使用示例
project_start = date(2023, 12, 1)
project_end = date(2024, 2, 29)project = ProjectCalendar("新产品开发", project_start, project_end)
project.add_milestone("需求分析完成", date(2023, 12, 15))
project.add_milestone("开发完成", date(2024, 1, 31))
project.add_milestone("测试完成", date(2024, 2, 20))project.generate_project_calendar()
总结
calendar 模块是 Python 中处理日历相关功能的强大工具,主要特点:
基本功能:闰年判断、月份天数、星期计算
日历生成:文本日历、HTML 日历
日期计算:工作日计算、日期范围
自定义功能:可以扩展和自定义日历显示
常用函数速查表
函数 | 描述 |
---|---|
calendar.isleap(year) | 判断是否为闰年 |
calendar.leapdays(y1, y2) | 两个年份间的闰年数 |
calendar.monthrange(year, month) | 返回月份的第一天星期和天数 |
calendar.monthcalendar(year, month) | 返回月份日历矩阵 |
calendar.month(year, month) | 返回月份文本日历 |
calendar.calendar(year) | 返回年份文本日历 |
calendar.HTMLCalendar() | 创建HTML日历对象 |
calendar 模块特别适合需要生成日历、计算日期、管理日程的应用场景。结合 datetime 模块使用,可以构建功能完整的日期时间处理系统。