1. calendar处理日期
calendar模块第一了Calendar类,其中封装了一些值的计算,如给定的一个月或一年中的周日期。另外,TextCalendar和HTMLCalendar类可以生成经过预格式化的输出。
1.1 格式化示例
prmonth()方法是一个简单的函数,可以生成月的格式化文本输出。
import calendar c = calendar.TextCalendar(calendar.SUNDAY) c.prmonth(2017, 7)
这个例子按照美国的惯例,将TextCalendar配置为一周从星期日开始。而默认则会使用欧洲惯例,即一周从星期一开始。这个例子会生成以下输出。
利用HTMLCalendar和formatmonth()可以生成一个类似的HTML表格。显示的输出看起来与纯文本的版本大致是一样的,不过会用HTML标记包围。各个表单元格有一个类属性对应星期几,从而可以通过CSS制定HTML的样式。
除了可用的默认格式外,要想以其他的某种格式生成输出,可以使用calendar计算日期,并把这些值组织为周和月区间,然后迭代处理结果。对于这个任务,Calendar的weekheader()、monthcalendar()和yeardays2calendar()方法尤其有用。
调用yeardays2calendar()会生成一个由"月行"列表构成的序列。每个月列表包含一些月,每个月是一个周列表。周是元组列表,元组则由日编号(1~31)是星期几编号(0~6)构成。当月以外的日编号为0。
import calendar import pprint cal = calendar.Calendar(calendar.SUNDAY) cal_data = cal.yeardays2calendar(2020, 3) print('len(cal_data) :', len(cal_data)) top_months = cal_data[0] print('len(top_months) :', len(top_months)) first_month = top_months[0] print('len(first_month) :', len(first_month)) print('first_month:') pprint.pprint(first_month, width=65)
调用yeardays2calendar(2020,3)会返回2020年的数据,按每行3个月组织。
这等价于formatyear()使用的数据。
import calendar cal = calendar.TextCalendar(calendar.SUNDAY) print(cal.formatyear(2020, 2, 1, 1, 3))
如果给定相同的参数,则formatyear()会生成以下输出。
1.2 本地化环境
如果不是为了当前本地化环境,而是要为另外一个本地化环境生成一个格式化的日历,那么可以使用LocaleTextCalendar或LocaleHTMLCalendar。
import calendar c = calendar.LocaleTextCalendar(locale='en_US') c.prmonth(2020, 2) print() c = calendar.LocaleTextCalendar(locale='fr_FR') c.prmonth(2020, 3)
一周的第一天不属于本地化环境的设置。这个值取自calendar类的参数,常规的TextCalendar类也是如此。
1.3 计算日期
尽管calendar模块主要强调采用不同格式打印完整的日历,但它还是提供了另外一些函数,对采用其他方式处理日期很有用,如为一个重复事件计算日期。例如,Python Atlanta用户组每月的第二个星期四召开一次会议。要计算一年中的会议日期,可以使用monthcalendar()的返回值。
import calendar import pprint pprint.pprint(calendar.monthcalendar(2020, 7))
有些日期的值为0。这说明这几天对应的星期几尽管在给定的当前月份里,但它们实际上属于另一个月。
一周中的第一天默认为星期一。可以通过调用setfirstweekday()来改变这个设置,不过由于calendar模块包含了一些常量来索引monthcalendar()返回的日期区间,所以在这种情况下更方便的做法是跳过这一步。
要计算一年的会议日期,假设是每个月的第二个星期四,那么可以查看monthcalendar()的输出,找到星期四对应的日期。一个月的第一周和最后一周都要填充0值作为占位符,分别表示相应日期实际上在前一个月或下一个月。例如,如果一个月从星期五开始,那么第一周星期四位置上的值就是0。