关于python:calendar-日历相关│Python标准库

2次阅读

共计 10341 个字符,预计需要花费 26 分钟才能阅读完成。

前情提醒: 测试代码中,右尖括号(>)表示命令行中输出的命令;独自一行并以井字符(#)结尾的为输入内容;库的导入仅在本文的第一个测试代码中展示,其余代码块均省略库的导入代码。

  • 零碎类型: Windows 10
  • python 版本: Python 3.9.0

calendar 模块提供了与日历无关的函数与类。其中既蕴含了可不便用于计算或信息处理的日历格局,也蕴含了可直观展现的日历格局,甚至有用于网页展现的 html 格局.

calendar 模块提供了三个类,也提供了一些属性和函数进行快捷操作。calendar 模块提供的函数将散布在同性能的类中介绍。

calendar 模块提供了 4 个属性,所有属性返回的数据都是可迭代对象:

  • calendar.day_name : 在以后语言环境下示意星期几的数组
  • calendar.day_abbr : 在以后语言环境下示意星期几缩写的数组
  • calendar.month_name : 在以后语言环境下示意一年中月份的数组。这里为了事实习惯,一月的月号为 1,所以此数组的元素个数为 13 个,其中索引值为 0 的元素的值为空
  • calendar.month_abbr : 在以后语言环境下示意月份简写的数组。这里为了事实习惯,一月的月号为 1,所以此数组的元素个数为 13 个,其中索引值为 0 的元素的值为空
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']

Calendar 类

class calendar.Calendar(firstweekday=0)
参数:
    firstweekday: int, 指定一周的第一天, 0 示意星期一, 6 示意星期天, 默认为 0

创立已 Calendar 对象,Calendar 对象提供了一些办法,这些办法能够用于各种场景的与日历无关的数据,失去的数据并不便于查看,但不便计算。

iterweekdays()
iterweekdays()
返回值:
    可迭代对象

返回一个可迭代对象,蕴含一星期对应的枚举值,排序在第一个元素的枚举值与类参数 firstweekday 的值统一。

import calendar

cc = calendar.Calendar(1)
print(list(cc.iterweekdays()))
# [1, 2, 3, 4, 5, 6, 0]

cc = calendar.Calendar(4)
print(list(cc.iterweekdays()))
# [4, 5, 6, 0, 1, 2, 3]

PS: 无论一周的第一天设置为星期几,这与七天中每天对应的枚举值无关。星期一的枚举值肯定是 0,星期二的枚举值肯定是 1,以此类推,星期天的枚举值肯定是 6

itermonthdates()
itermonthdates(year, month)
参数:
    year: 年
    month: 月
返回值:
    可迭代对象

返回一个可迭代对象,蕴含某年某月当月的全副日期,日期对象为 datetime 对象。

若本月月初和月末不是一个残缺的周,也会返回其余月份的日期用于组成一个残缺的日期。也就是说某一周的日期里,蕴含指定月份的日期,也蕴含其余月份的日期,那么本办法返回的日期中也蕴含这些在同一周内的其余月份的日期。

cc = calendar.Calendar(0)
print(list(cc.itermonthdates(2021, 1)))
# [# datetime.date(2020, 12, 28), datetime.date(2020, 12, 29),
# datetime.date(2020, 12, 30), datetime.date(2020, 12, 31),
# datetime.date(2021, 1, 1), datetime.date(2021, 1, 2),
# ......
# datetime.date(2021, 1, 30), datetime.date(2021, 1, 31)
# ]

PS: 此模块的一些办法返回值内容过多,此文章将会省略一部分返回内容。

itermonthdays()
itermonthdays(year, month)
itermonthdays2(year, month)
itermonthdays3(year, month)
itermonthdays4(year, month)
参数:
    year: 年
    month: 月
返回值:
    可迭代对象

本办法是四胞胎兄弟,它们都返回一个可迭代对象,蕴含某年某月当月的全副日期。然而它们返回的元素的内容却不尽相同。

它们与 itermonthdates() 函数相似,在返回的日期中,月初和月末那一周种同周不同月的日期也会展出进去,然而与 itermonthdates() 函数不同的是,不在指定月份的日期对象展现的日期的值是 0

itermonthdays() 函数,可称说为一号函数,可迭代对象的元素为日期对应的天数。

itermonthdays2() 函数,可称说为二号函数,可迭代对象的元素为由日期对应的天数和当天星期几的枚举值组成的元组。例如: (1, 5) 示意本月的一号,星期五。

itermonthdays3() 函数,可称说为三号函数,可迭代对象的元素为由年、月、日组成的元组。例如: (2021, 1, 1) 示意 2021 年 1 月 1 日。

itermonthdays4() 函数,可称说为四号函数,可迭代对象的元素为由年、月、日和当天星期示意的枚举值组成的元组。例如: (2021, 1, 1, 5) 示意 2021 年 1 月 1 日周六。

cc = calendar.Calendar(0)
'''一号函数'''
print(list(cc.itermonthdays(2021, 1)))
# [0, 0, 0, 0, 1, 2, ......, 30, 31]

'''二号函数'''
print(list(cc.itermonthdays2(2021, 1)))
# [(0, 0), (0, 1), (0, 2), (0, 3), (1, 4), (2, 5), ......, (30, 5), (31, 6)]

'''三号函数'''
print(list(cc.itermonthdays3(2021, 1)))
# [(2020, 12, 28), (2020, 12, 29), (2020, 12, 30), (2020, 12, 31), (2021, 1, 1),
#  (2021, 1, 2), (2021, 1, 3), (2021, 1, 4), (2021, 1, 5),
# ......
#  (2021, 1, 28), (2021, 1, 29), (2021, 1, 30), (2021, 1, 31)]

'''四号函数'''
print(list(cc.itermonthdays4(2021, 1)))
# [(2020, 12, 28, 0), (2020, 12, 29, 1), (2020, 12, 30, 2),
#  (2020, 12, 31, 3), (2021, 1, 1, 4), (2021, 1, 2, 5),
# ......
#  (2021, 1, 29, 4), (2021, 1, 30, 5), (2021, 1, 31, 6)]
获取指定年月的周列表
monthdatescalendar(year, month)
monthdays2calendar(year, month)
monthdayscalendar(year, month)
参数:
    year: 年
    month: 月
返回值:
    列表, 一个多维列表

以上三个函数都返回指定年月的日期数据,所返回的数据是一个列表,在列表外部,列表的元素是以周为单位宰割的子列表,子列表中的元素才是日期数据。

以上三个函数的不同点就在子列表中的日期数据:

monthdatescalendar() 函数能够简称为 日期数据函数,因为这个函数的返回值内的日期数据是以 datetime.date 对象展现的。

monthdayscalendar() 函数能够简称为 一号函数,这个函数的返回值内的日期数据是以代表日期的数字的模式展现的。

monthdays2calendar() 函数能够简称为 二号函数,这个函数的返回值内的日期数据是以代表日期的数字和当天星期示意的枚举值组成的二元元组的模式展现的。

一号函数 二号函数 中,如果某个日期数据不是指定年月内的日期,那么代表日期的数字将是 0

cc = calendar.Calendar(0)

'''返回 datetime.date'''
print(cc.monthdatescalendar(2021, 1))
# [#   [datetime.date(2020, 12, 28), ......, datetime.date(2021, 1, 3)],
#   ......
#   [datetime.date(2021, 1, 25), ......, datetime.date(2021, 1, 31)]
# ]

'''返回日期代表的数字'''
print(cc.monthdayscalendar(2021, 1))
# [#   [0, 0, 0, 0, 1, 2, 3], ......, [25, 26, 27, 28, 29, 30, 31]
# ]

'''返回日期代表的数字与当天星期示意的枚举值组成的二元元组'''
print(cc.monthdays2calendar(2021, 1))
# [#   [(0, 0), (0, 1), (0, 2), (0, 3), (1, 4), (2, 5), (3, 6)],
#   ......
#   [(25, 0), (26, 1), (27, 2), (28, 3), (29, 4), (30, 5), (31, 6)]
# ]

calendar 模块中,calendar.monthcalendar(year, month) 快捷函数与 monthdayscalendar() 办法相似,返回值雷同。

获取可用于格式化的指定年的数据

yeardatescalendar(year, width=3)
yeardayscalendar(year, width=3)
yeardays2calendar(year, width=3)
参数:
    year: 年
    width: 关键字参数, 每几个月分为一组, 默认为 3
返回值:
    列表, 多维列表

返回一个多维列表,列表内容为指定年的日期数据。列表的元素是以参数 width 设定的月份分组,指定数量的月份为一组,所以列表的元素个数就是分组个数,为了不便辨别多维度 (层级) 的列表,咱们能够将整个列表称为 年列表 年列表 下代表月份分组的子列表称为 月分组子列表。以后格局为: [[月分组子列表], ......, [月分组子列表]]

月分组子列表 的元素就是属于本组的月份,月份数据格式也是列表,能够称为 月子列表 月分组子列表 格局为: [[月子列表], ......, [月子列表]]

月子列表 的元素是属于本月的周,周的数据格式仍旧是列表,能够称为 周子列表 月子列表 格局为: [[周子列表], ......, [月子列表]]

对于三个函数而言,以上局部数据格式都雷同,三个函数不同的就是 周子列表 中的元素,没错,就是日期数据。这里的 周子列表 中的周数据也是秉承着 Calendar 类的特定,属于本周然而不属于本月的日期也会展现,然而若是展现日期代表的数字时,会展现为 0

yeardatescalendar() 函数返回值中的日期数据格式为 datetime.date 对象格局。yeardayscalendar() 函数返回值中日期数据为日期代表的数字。yeardays2calendar() 函数返回值中日期数据为日期代表的数字与当天星期示意的枚举值组成的二元元组。

'''备注: 返回数据过于宏大, 受限于篇幅, 测试示例中仅具体展现了列表格局'''
cc = calendar.Calendar(0)

'''日期数据为日期代表的数字'''
print(cc.yeardayscalendar(2021, width=2))
# [
#     [
#         [#             [0, 0, 0, 0, 1, 2, 3], ......, [25, 26, 27, 28, 29, 30, 31],
#         ],
#         [#             [1, 2, 3, 4, 5, 6, 7], ......, [22, 23, 24, 25, 26, 27, 28],
#         ],
#     ],
#     ......,
#     [
#         [#             [1, 2, 3, 4, 5, 6, 7], ......, [29, 30, 0, 0, 0, 0, 0],
#         ],
#         [#             [0, 0, 1, 2, 3, 4, 5], ......, [27, 28, 29, 30, 31, 0, 0],
#         ],
#     ],
# ]

'''日期数据为是以代表日期的数字和当天星期示意的枚举值组成的二元元组'''
print(cc.yeardays2calendar(2021, width=2))
# [
#     [
#         [#             [(0, 0), ......, (3, 6)], ......, [(25, 0), ......, (31, 6)],
#         ],
#         [#             [(1, 0), ......, (7, 6)], ......, [(22, 0), ......, (28, 6)],
#         ],
#     ],
#     ......,
#     [
#         [#             [(1, 0), ......, (7, 6)], ......, [(29, 0), ......, (0, 6)],
#         ],
#         [#             [(0, 0), ......, (5, 6)], ......, [(27, 0), ......, (0, 6)],
#         ],
#     ],
# ]

'''日期数据为 datatime.data 对象'''
print(cc.yeardatescalendar(2021, width=2))
# [
#     [
#         [#             [datetime.date(2020, 12, 28), ......, datetime.date(2021, 1, 3),],
#             ......,
#             [datetime.date(2021, 1, 25), ......, datetime.date(2021, 1, 31),],
#         ],
#         [#             [datetime.date(2021, 2, 1)), ......, datetime.date(2021, 2, 7),],
#             ......,
#             [datetime.date(2021, 2, 22), ......, datetime.date(2021, 2, 28),],
#         ],
#     ],
#     ......,
#     [
#         [#             [datetime.date(2021, 11, 1), ......, datetime.date(2021, 11, 7),],
#             ......,
#             [datetime.date(2021, 11, 29), ......, datetime.date(2021, 12, 5),],
#         ],
#         [#             [datetime.date(2021, 11, 29), ......, datetime.date(2021, 12, 5),],
#             ......,
#             [datetime.date(2021, 12, 27), ......, datetime.date(2022, 1, 2),],
#         ],
#     ],
# ]

TextCalendar 类

class calendar.TextCalendar(firstweekday=0)
参数:
    firstweekday: int, 指定一周的第一天, 0 示意星期一, 6 示意星期天, 默认为 0

TextCalendar 实例化对象,可通过 TextCalendar 实例化对象提供的办法获取纯文本的日历数据,通常用于查看,无奈用于计算。

获取一个月的日历数据
formatmonth(theyear, themonth, w=0, l=0)
prmonth(theyear, themonth, w=0, l=0)
参数
    theyear: 年份
    themonth: 月份
    w: 日期宽度, 日期内容始终为居中
    l: 每星期占用的行数

formatmonth() 函数与 prmonth() 函数的目标都是给出指定年月当月的日历数据,然而 formatmonth() 函数是以返回值的形式反馈的,prmonth() 函数则是间接打印数据。

tc = calendar.TextCalendar(0)

'''返回值'''
print(tc.formatmonth(2021, 1))
#     January 2021
# 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

'''间接打印'''
tc.prmonth(2021, 1)
#     January 2021
# 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 模块的快捷函数中,calendar.prmonth(theyear, themonth, w=0, l=0)prmonth() 办法雷同,都是间接打印出整个月的日历; 另一个快捷函数 calendar.month(theyear, themonth, w=0, l=0)formatmonth() 办法雷同,是返回指定月份的日历。

获取一年的日历数据
formatyear(theyear, w=2, l=1, c=6, m=3)
pryear(theyear, w=2, l=1, c=6, m=3)
参数:
    theyear: 年份
    w: 日期宽度, 日期内容始终为居中
    l: 每星期占用的行数
    c: 月与月之间的距离大小
    m: 每列可展现多少个月份

formatyear() 函数与 pryear() 函数的目标都是给出指定年的日历数据,然而 formatyear() 函数是以返回值的形式反馈的,pryear() 函数则是间接打印数据。

年日历数据格式能够看做是 12 个月日历数据的汇总,因篇幅起因就不展现测试示例了。

同获取指定月份日历数据的两个办法一样,获取指定年份的日历数据也有两个对应的快捷函数,calendar.prcal(year, w=0, l=0, c=6, m=3) 快捷函数对应 pryear() 办法,calendar.calendar(year, w=2, l=1, c=6, m=3) 快捷函数对应 formatyear() 办法。

HTMLCalendar 类

class calendar.HTMLCalendar(firstweekday=0)
参数:
    firstweekday: int, 指定一周的第一天, 0 示意星期一, 6 示意星期天, 默认为 0

HTMLCalendar 实例化对象,能够通过 HTMLCalendar 实例化对象提供的办法生成能够在网页中展现的 HTML 日历。并且也提供了一些属性来批改各种标签的类名,便于批改款式。

formatmonth() 办法获取一个展现指定月份日历的 HTML 表格。

formatmonth(theyear, themonth, withyear=True)
参数:
    theyear: 年
    themonth: 月
    withyear: 布尔值, 默认为 True, 若为 True, 则表头内容会蕴含年份, 否则不蕴含
返回值:
    str, 一个 table 标签, 蕴含指定月份日历数据

formatyear() 办法获取一个展现指定年份日历的 HTML 表格。

formatyear(theyear, width=3)
参数:
    theyear: 年
    width: 默认值为 3, 示意一行可显示的月份数量
返回值:
    str, 一个 table 标签, 蕴含指定年份日历数据

formatyearpage() 办法返回一个残缺的 HTML 页面,其中次要内容就是指定年份日历数据。

formatyearpage(theyear, width=3, css='calendar.css', encoding=None)
参数:
    theyear: 年
    width: 默认值为 3, 示意一行可显示的月份数量
    css: 导入的 css 文件, 用于丰盛日历表款式
    encoding: 编码, 若为 None 则应用零碎默认编码
返回值:
    str, 一个残缺的 HTML 页面代码

应用以上办法生成的 HTML 代码中,每个标签都会有 class 属性,这些 class 属性是零碎默认的,可能会对我的项目产生抵触或者命名规定不匹配等状况,HTMLCalendar 类给出了一系列可批改属性来扭转这些标签上的 class 属性。

  • cssclasses : 对应星期一到星期天的 class 名称列表,列表元素必须有 7 个,默认为: ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
  • cssclass_noday : 在某周内,某日期在上月或下月时,此日期 td 标签的 class
  • cssclasses_weekday_head : 失常日期的 td 标签的 class,默认为以后日期代表的星期几对应的 class 名。
  • cssclass_month_head: 月历的表头 class,默认为 month
  • cssclass_month : 月历的 table 标签的 class,默认为 month
  • cssclass_year : 年历的 table 标签的 class,默认为 year
  • cssclass_year_head : 年历的表头 class,默认为 year

将以下 css 复制粘贴到某个 css 文件中,并 python 代码,在浏览器中关上生成的 HTML 文件,来查看应用 python 生成的日历。

PS: 此 css 是在网络中寻找的,应用的都是标签名,对 HTMLCalendar 类中 class 相干内容无学习效果。

table {width: 100%;}
table tr th {text-align: center;font-size: 16px;background-color: #316497;color: #99ccff;}
table tr td {width: 10%;border: 1px solid #555;vertical-align: top;height: 120px;padding: 2px;}
td.noday {background-color: #eee;}
td.filled {background-color: #99ccff;}
td.today {border: 4px solid #316497;}
.dayNumber {font-size: 16px !important;font-weight: bold;}
a {font-size: 10px;}

运行以下 python 代码:

hc = calendar.HTMLCalendar(0)

with open('./test.html', 'wb') as f:
    f.write(hc.formatyearpage(2021, css='calendar.css'))

在运行目录下,会生成一个名称为 test.html 的文件,在浏览器关上这个文件即可看到成果。

快捷函数

在类的介绍中,共有 5 个快捷函数与类中的办法含意统一,就间接在对应办法的介绍中阐明了,没有留神到的小伙伴能够向上翻阅回顾一下。残余的快捷函数就留到这里一起介绍吧。

setfirstweekday() 函数设置一周是以周几为终点计算的。设置时能够应用代表星期的常量或者枚举值。

calendar.setfirstweekday(weekday)
参数:
    weekday: 示意星期的常量或枚举值, 枚举值即对应的数字, 星期一到星期日的
             常量则别离为:MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY 和 SUNDAY
返回值:
    None

firstweekday() 函数获取一周的第一天是周几。无论设置时应用的是代表星期的常量还是代表星期的枚举值,返回的肯定是枚举值。

calendar.firstweekday()
返回值:
    int, 代表星期的枚举值

isleap() 函数判断指定年是否是平年,如果是平年则返回 True,否则返回 False

calendar.isleap(year)
参数:
    year: 年份
返回值:
    布尔值

leapdays() 函数获取某个范畴年份 (y1y2 年之间) 的平年数量。

calendar.leapdays(y1, y2)
参数:
    y1, y2: 年份
返回值:
    int

weekday() 函数获取某年某月某日是星期几,返回代表星期的枚举值。

calendar.weekday(year, month, day)
参数:
    year: 年
    month: 月
    day: 日
返回值:
    int, 代表星期的枚举值

weekheader() 函数列出所有星期的英文缩写头,能够应用参数 n 来指定缩写单词的字母数量。返回一个字符串,每个英文缩写头以双空格隔开。

calendar.weekheader(n)
参数:
    n: 缩写字母的数量
返回值:
    str, 每个缩写以双空格隔开

monthrange() 函数获取指定年月当月第一天是星期几,并获取当月天数。将两个数据组合成一个元组返回.

calendar.monthrange(year, month)
参数:
    year: 年
    month: 月
返回值:
    二元元组,某月第一天星期对应的枚举值和当月天数组成

参考资料

官网文档: https://docs.python.org/zh-cn/3/library/calendar.html#calendar.HTMLCalendar

源代码: Lib/calendar.py

公众号 :「python 杂货铺」,专一于 python 语言及其相干常识。挖掘更多原创文章,期待您的关注。

正文完
 0