作用:calendar模块实现了一些类来处理日期,管理面向年、月和周的值。
Python版本:I.4版本,2.5中做了更新
calendar模块定义了 Calendar类,其中封装了一些值的计算,如给定的一个月或一年中的 周几。另外,TextCalendar和HTMLCalendar类可以生成经过预格式化的输出。
模块概览
- calendar.calendar(year,w=2,l=1,c=6)
返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c。 每日宽度间隔为w字符。每行长度为21* W+18+2* C。l是每星期行数。 - calendar.firstweekday( )
返回当前每周起始日期的设置。默认情况下,首次载入caendar模块时返回0,即星期一。 - calendar.isleap(year)
是闰年返回True,否则为false。 - calendar.leapdays(y1,y2)
返回在Y1,Y2两年之间的闰年总数。 - calendar.month(year,month,w=2,l=1)
返回一个多行字符串格式的year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行的长度为7* w+6。l是每星期的行数。 - calendar.monthcalendar(year,month)
返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。Year年month月外的日期都设为0;范围内的日子都由该月第几日表示,从1开始。 - calendar.monthrange(year,month)
返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码。日从0(星期一)到6(星期日);月从1到12。 - calendar.prcal(year,w=2,l=1,c=6)
相当于 print calendar.calendar(year,w,l,c). - calendar.prmonth(year,month,w=2,l=1)
相当于 print calendar.calendar(year,w,l,c)。 - calendar.setfirstweekday(weekday)
设置每周的起始日期码。0(星期一)到6(星期日)。 - calendar.timegm(tupletime)
和time.gmtime相反:接受一个时间元组形式,返回该时刻的时间戳(1970纪元后经过的浮点秒数)。 - calendar.weekday(year,month,day)
返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。
格式化
prmonth方法是一个简单的函数,可以生成一个月的格式化文本输出。
import calendar
cal = calendar.TextCalendar(calendar.SUNDAY)
print cal.formatyear(2011, 2, 1, 1, 3)
这个例子按照美国的惯例,将TextCalendar配置为一周从星期日开始。默认会使用欧洲惯例,即一周从星期一开始。
输出如下:
2011
January February March
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 2 3 4 5 1 2 3 4 5
2 3 4 5 6 7 8 6 7 8 9 10 11 12 6 7 8 9 10 11 12
9 10 11 12 13 14 15 13 14 15 16 17 18 19 13 14 15 16 17 18 19
16 17 18 19 20 21 22 20 21 22 23 24 25 26 20 21 22 23 24 25 26
23 24 25 26 27 28 29 27 28 27 28 29 30 31
30 31
April May June
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 1 2 3 4 5 6 7 1 2 3 4
3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
24 25 26 27 28 29 30 29 30 31 26 27 28 29 30
July August September
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 1 2 3 4 5 6 1 2 3
3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10
10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17
17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24
24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30
31
October November December
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 2 3 4 5 1 2 3
2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10
9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17
16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24
23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31
30 31
[Finished in 0.1s]
利用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(2011, 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)
调用yeardays2calendar(2011, 3)会返回20ll年的数据,按每栏3个月组织。
len(cal_data) : 4
len(top_months) : 3
len(first_month) : 6
first_month:
[[(0, 6), (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 5)],
[(2, 6), (3, 0), (4, 1), (5, 2), (6, 3), (7, 4), (8, 5)],
[(9, 6), (10, 0), (11, 1), (12, 2), (13, 3), (14, 4), (15, 5)],
[(16, 6), (17, 0), (18, 1), (19, 2), (20, 3), (21, 4), (22, 5)],
[(23, 6), (24, 0), (25, 1), (26, 2), (27, 3), (28, 4), (29, 5)],
[(30, 6), (31, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]]
[Finished in 0.1s]
这等价于formatyear使用的数据。
import calendar
cal = calendar.TextCalendar(calendar.SUNDAY)
print cal.formatyear(2011, 2, 1, 1, 3)
对于相同的参数,formatyear会生成以下输出。
2011
January February March
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 2 3 4 5 1 2 3 4 5
2 3 4 5 6 7 8 6 7 8 9 10 11 12 6 7 8 9 10 11 12
9 10 11 12 13 14 15 13 14 15 16 17 18 19 13 14 15 16 17 18 19
16 17 18 19 20 21 22 20 21 22 23 24 25 26 20 21 22 23 24 25 26
23 24 25 26 27 28 29 27 28 27 28 29 30 31
30 31
April May June
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 1 2 3 4 5 6 7 1 2 3 4
3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
24 25 26 27 28 29 30 29 30 31 26 27 28 29 30
July August September
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 1 2 3 4 5 6 1 2 3
3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10
10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17
17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24
24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30
31
October November December
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 2 3 4 5 1 2 3
2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10
9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17
16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24
23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31
30 31
[Finished in 0.1s]
day_name、day_abbr、month_name和month_abbr模块属性对于生成定制格式的输出很有用(例如,在HTML输出中包含链接)。这些属性会针对当前本地化环境正确地自动配置。
计算日期
尽管calendar模块主要强调采用不同格式打印完整的日历,它还提供了另外一些函数,对采用其他方式处理日期很有用,如为一个重复亊件计算日期。例如,Python Atlanta Users Group 毎月的第二个星期四会召开一次会议。要计算一年中的会议日期,可以使用monthcalendar的返回值
import calendar
import pprint
pprint.pprint(calendar.monthcalendar(2011, 7))
有些日期的值为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]]
[Finished in 0.1s]
一周中的第一天默认为星期一。可以通过调用setfirstweekday改变这个设置,不过由于calendar模块包含一些常量来索引monthcalendar()返回的日期区间,所以在这种情况下跳过这一步会更方便。
要计算2011年的会议日期,假设是每个月的第二个星期四,0值指示第一周的星期四是否包含在这个月内(或者不包含在这个月中,比如这个月从星期五开始)。
import calendar
# Show every month
for month in range(1, 13):
# Compute the dates for each week that overlaps the month
c = calendar.monthcalendar(2011, month)
first_week = c[0]
second_week = c[1]
third_week = c[2]
# If there is a Thursday in the first week, the second Thursday
# is in the second week. Otherwise, the second Thursday must
# be in the third week.
if first_week[calendar.THURSDAY]:
meeting_date = second_week[calendar.THURSDAY]
else:
meeting_date = third_week[calendar.THURSDAY]
print '%3s: %2s' % (calendar.month_abbr[month], meeting_date)
所以,这一年的会议日程为:
Jan: 13
Feb: 10
Mar: 10
Apr: 14
May: 12
Jun: 9
Jul: 14
Aug: 11
Sep: 8
Oct: 13
Nov: 10
Dec: 8
[Finished in 0.1s]