5.4. calendar — 日期操作
ose: 日历模块是实现用于处理日期的类,以管理面向年/月/周的值。
calendar
模块定义了 Calendar
类, 它封装了值的计算, 例如给定月份或年份中周的日期。此外, TextCalendar
和 HTMLCalendar
类可以生成预格式化的输出。
格式化示例
该 prmonth()
方法是一个简单的函数,可以生成一个月的格式化文本输出。
calendar_textcalendar.py
import calendar
c = calendar.TextCalendar(calendar.SUNDAY)
c.prmonth(2017, 7)
根据美国惯例,该示例配置 TextCalendar
以周日开始周。默认是欧洲惯例,使用星期一开始一周的。
输出如下:
$ python3 calendar_textcalendar.py
July 2017
Su Mo Tu We Th Fr Sa
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
可以使用 HTMLCalendar
和 formatmonth()
生成类似 HTML 的表。 呈现的输出看起来与纯文本版本大致相同,但是用 HTML 标记包装。每个表格单元格都有一个与星期几相对应的类属性,所以这种 HTML 可以通过 CSS 设置样式。
要以不同于其中一个可用默认格式生成输出,请使用 calendar
计算日期格式并将值组织为周和月的范围,然后迭代结果。Calendar
中的 weekheader()
, monthcalendar()
, 和 yeardays2calendar()
方法对此特别有用。
调用 yeardays2calendar()
会生成一系列 “月份行” 列表。每个列表包括月份作为另一个周的列表。这几周是由日期编号(1-31)和工作日编号(0-6)组成的元组列表。超出月份的天数为0。
calendar_yeardays2calendar.py
import calendar
import pprint
cal = calendar.Calendar(calendar.SUNDAY)
cal_data = cal.yeardays2calendar(2017, 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(2017, 3)
retu返回2017年的数据,每行三个月。
$ python3 calendar_yeardays2calendar.py
len(cal_data) : 4
len(top_months) : 3
len(first_month) : 5
first_month:
[[(1, 6), (2, 0), (3, 1), (4, 2), (5, 3), (6, 4), (7, 5)],
[(8, 6), (9, 0), (10, 1), (11, 2), (12, 3), (13, 4), (14, 5)],
[(15, 6), (16, 0), (17, 1), (18, 2), (19, 3), (20, 4), (21,
5)],
[(22, 6), (23, 0), (24, 1), (25, 2), (26, 3), (27, 4), (28,
5)],
[(29, 6), (30, 0), (31, 1), (0, 2), (0, 3), (0, 4), (0, 5)]]
这等效于使用 formatyear()
获得的数据。
calendar_formatyear.py
import calendar
cal = calendar.TextCalendar(calendar.SUNDAY)
print(cal.formatyear(2017, 2, 1, 1, 3))
对于相同的参数, formatyear()
生成如下输出:
$ python3 calendar_formatyear.py
2017
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 2 3 4 5 6 7 1 2 3 4 1 2 3 4
8 9 10 11 12 13 14 5 6 7 8 9 10 11 5 6 7 8 9 10 11
15 16 17 18 19 20 21 12 13 14 15 16 17 18 12 13 14 15 16 17 18
22 23 24 25 26 27 28 19 20 21 22 23 24 25 19 20 21 22 23 24 25
29 30 31 26 27 28 26 27 28 29 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 1 2 3 4 5 6 1 2 3
2 3 4 5 6 7 8 7 8 9 10 11 12 13 4 5 6 7 8 9 10
9 10 11 12 13 14 15 14 15 16 17 18 19 20 11 12 13 14 15 16 17
16 17 18 19 20 21 22 21 22 23 24 25 26 27 18 19 20 21 22 23 24
23 24 25 26 27 28 29 28 29 30 31 25 26 27 28 29 30
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 1 2 3 4 5 1 2
2 3 4 5 6 7 8 6 7 8 9 10 11 12 3 4 5 6 7 8 9
9 10 11 12 13 14 15 13 14 15 16 17 18 19 10 11 12 13 14 15 16
16 17 18 19 20 21 22 20 21 22 23 24 25 26 17 18 19 20 21 22 23
23 24 25 26 27 28 29 27 28 29 30 31 24 25 26 27 28 29 30
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 2 3 4 5 6 7 1 2 3 4 1 2
8 9 10 11 12 13 14 5 6 7 8 9 10 11 3 4 5 6 7 8 9
15 16 17 18 19 20 21 12 13 14 15 16 17 18 10 11 12 13 14 15 16
22 23 24 25 26 27 28 19 20 21 22 23 24 25 17 18 19 20 21 22 23
29 30 31 26 27 28 29 30 24 25 26 27 28 29 30
31
day_name
, day_abbr
, month_name
, 和 month_abbr
模块用于生产自定义格式化的输出(即,包括HTML输出链路)是有用的。它们会针对当前区域设置自动正确配置。
地区
要为当前默认设置之外的地区生成格式化的日历,我们可以使用 LocaleTextCalendar
或 LocaleHTMLCalendar
。
calendar_locale.py
import calendar
c = calendar.LocaleTextCalendar(locale='en_US')
c.prmonth(2017, 7)
print()
c = calendar.LocaleTextCalendar(locale='fr_FR')
c.prmonth(2017, 7)
一周的第一天并不是地区设置的一部分,而且数值是从参数获取到 calendar 类,就像常规的 TextCalendar
一样。
$ python3 calendar_locale.py
July 2017
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
juillet 2017
Lu Ma Me Je Ve Sa Di
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
计算日期
虽然日历模块主要侧重于以各种格式打印完整日历,但它还提供了以其他方式处理日期的有用功能,例如计算重复事件的日期。例如,Python 亚特兰大用户组在每个月的第二个星期四开会。要计算一年会议的日期,请使用 monthcalendar()
的返回值。
calendar_monthcalendar.py
import calendar
import pprint
pprint.pprint(calendar.monthcalendar(2017, 7))
有些天是 0 值。 这些是与给定月份重叠的一周中的日期,但这是另一个月的一部分。
$ python3 calendar_monthcalendar.py
[[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, 0]]
一周的第一天默认为星期一。可以通过调用 setfirstweekday()
来改变它,但由于日历模块包含用于索引到 monthcalendar()
返回的日期范围的常量,因此在这种情况下跳过该步骤更方便。
要计算一年的小组会议日期,假设它们总是在每个月的第二个星期四,请查看 monthcalendar()
的输出以查找星期四下降的日期。本月的第一周和最后一周填充 0 值作为前一个月或后一个月的天数的占位符。 例如,如果一个月在星期五开始,则星期四位置第一周的值将为 0。
calendar_secondthursday.py
import calendar
import sys
year = int(sys.argv[1])
# 显示每月
for month in range(1, 13):
# 计算与月份重叠的每周的日期
c = calendar.monthcalendar(year, month)
first_week = c[0]
second_week = c[1]
third_week = c[2]
# 如果第一周有星期四,
# 第二个星期四是第二周#。
# 否则,第二个星期四必须在
# 第三周。
if first_week[calendar.THURSDAY]:
meeting_date = second_week[calendar.THURSDAY]
else:
meeting_date = third_week[calendar.THURSDAY]
print('{:>3}: {:>2}'.format(calendar.month_abbr[month],
meeting_date))
所以今年的会议日程是:
$ python3 calendar_secondthursday.py 2017
Jan: 12
Feb: 9
Mar: 9
Apr: 13
May: 11
Jun: 8
Jul: 13
Aug: 10
Sep: 14
Oct: 12
Nov: 9
Dec: 14
也可以看看
- calendar 标准库文档
time
-- 底层时间函数。datetime
-- 处理日期值,包括时间戳和时区。locale
-- 区域设置。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。