python标准库中处理时间、日期的主要是time、datetime和calendar这3个库,尽管一些第三方库如dateutil、Arrow、pendulum、moment、maya、Delorean、When.py等在时间和日期处理方面扩展了很多功能,使得处理更加简洁或人性化,但标准库处理时间和日期仍然是最常见和常用的。
time
库提供了近30个方法和10多个常量,是python处理时间相关的数据类型的基础。time
提供的方法主要有3类:时间获取、时间转换和时间相关的操作。
时间的表示方式主要有3种:
以上3中表示形式在time
中都有体现:
import time
time.time() # 时间戳:1568629886.590658
time.localtime() # 结构体时间:time.struct_time(tm_year=2019, /
# tm_mon=9, tm_mday=16, tm_hour=18, tm_min=31, /
# tm_sec=56, tm_wday=0, tm_yday=259, tm_isdst=0)
# 注意这个时间结构体是一个元组,不能通过类似time.localtime()['tm_min']来取值
time.ctime() # 'Mon Sep 16 18:31:40 2019'
以下是获取时间的常用方法:
方法 | 作用 | 备注 |
---|---|---|
time.time() | 时间戳,返回浮点数的秒数,以epoch为起点,截止当前时间,时区为标准时间 | 无参数 |
time.time_ns() | 时间戳,返回浮点数的纳秒数,以epoch为起点,截止当前时间,时区为标准时间 | 无参数 |
time.gmtime([secs]) | 将时间戳转换为为单位的时间转换为标准时间下的结构体元组 | 参数为以秒为单位的数,默认为time.time() |
time.localtime([secs]) | 将时间戳转换为为单位的时间转换为系统所在时区下的结构体元组 | 参数为以秒为单位的数,默认为time.time() |
time.ctime([secs]) | 返回的时间转换为表示本地时间的字符串,以epoch为起点,截止当前时间 | 参数为以秒为单位的数,默认为time.time() |
在结构体时间中,一般会返回一个包含8个元素的struct_time
对象,这个元组可以通过位置索引(index)访问:
索引 | 属性 | 值 | 含义 |
---|---|---|---|
0 | tm_year | (例如,1993) | 年份 |
1 | tm_mon | range [1, 12] | 月份 |
2 | tm_mday | range [1, 31] | 当月第几天 |
3 | tm_hour | range [0, 23] | 当日第几小时 |
4 | tm_min | range [0, 59] | 分 |
5 | tm_sec | range [0, 61] | 秒 |
6 | tm_wday | range [0, 6] ,周一为 0 | 周几 |
7 | tm_yday | range [1, 366] | 当年的第几天 |
8 | tm_isdst | 0, 1 或 -1 | 是否是夏令时 |
先来看时间戳的两种转化形式:
import time
sect = 1229711247
time.ctime(sect) # 'Sat Dec 20 02:27:27 2008'
time.gmtime(sect) # time.struct_time(tm_year=2008, tm_mon=12, /
# tm_mday=19, tm_hour=18, tm_min=27, tm_sec=27, /
# tm_wday=4, tm_yday=354, tm_isdst=0)
strptime
和strftime
实现了字符串和时间元组之间的相互转换,由于涉及将时间元组转化为一定格式的时间字符串,因此需要指定format
格式,一般用%
加一个字母来表示一个时间字段(文档中称为directive,“指令”):
指令 | 含义 |
---|---|
%a | 本地化的缩写星期中每日的名称 |
%A | 本地化的星期中每日的完整名称 |
%b | 本地化的月缩写名称 |
%B | 本地化的月完整名称 |
%c | 本地化的适当日期和时间表示 |
%d | 十进制数 [01,31] 表示的月中日。 |
%H | 十进制数 [00,23] 表示的小时(24小时制)。 |
%I | 十进制数 [01,12] 表示的小时(12小时制)。 |
%j | 十进制数 [001,366] 表示的年中日。 |
%m | 十进制数 [01,12] 表示的月。 |
%M | 十进制数 [00,59] 表示的分钟。 |
%p | 本地化的 AM 或 PM 。 |
%S | 十进制数 [00,61] 表示的秒。 |
%U | 十进制数 [00,53] 表示的一年中的周数(星期日作为一周的第一天) |
%w | 十进制数 [0(星期日),6] 表示的周中日。 |
%W | 十进制数 [00,53] 表示的一年中的周数(星期一作为一周的第一天)。 |
%x | 本地化的适当日期表示。 |
%X | 本地化的适当时间表示。 |
%y | 十进制数 [00,99] 表示的没有世纪的年份。 |
%Y | 十进制数表示的带世纪的年份。 |
%z | 时区偏移以格式 |
%Z | 时区名称(如果不存在时区,则不包含字符)。 |
%% | 字面的 ‘%’ 字符。 |
以下示例说明,字符串和时间元组之间的转换可以非常灵活:
import time
# 将字符串转化为时间元组
dt = '2018-12-31'
ts = time.strptime(dt, '%Y-%m-%d')
print(ts) # time.struct_time(tm_year=2018, /
# tm_mon=12, tm_mday=31, tm_hour=0, tm_min=0, tm_sec=0, /
# tm_wday=0, tm_yday=365, tm_isdst=-1)
# 将时间元组转化为字符串
tm = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
print(tm) # '2019-09-17 19:41:02'
time
模块中的其他函数除时间获取和转换外,time
另外还有2个方面的功能:使程序暂停指定时间和计算程序运行时间。
暂停指定时间用time.sleep(secs)
方法,根据文档,“暂停执行调用线程达到给定的秒数。参数可以是浮点数,以指示更精确的睡眠时间。实际的暂停时间可能小于请求的时间,因为任何捕获的信号将在执行该信号的捕获例程后终止sleep()
。此外,由于系统中其他活动的安排,暂停时间可能比请求的时间长任意量。”
计算程序运行时间方面,python标准库中提供了timeit
,这个库可以用命令行方式和调用方法的方式计算程序运行时间。time
中主要可以通过3个方法来测量程序运行时间:
函数 | 说明 |
---|---|
time.time() | 返回epoch为起点的系统时间的秒数,依赖于系统平台 |
time.perf_counter() | 返回一个CPU级别的精确的秒数。包括睡眠期间经过的时间,并且是系统范围的。返回值的参考点未定义,因此只有连续调用结果之间的差异才有效 |
time.process_time() | 返回当前进程的系统和用户CPU时间总和的值(以小数秒为单位)。它不包括睡眠期间经过的时间。根据定义,它在整个进程范围中。返回值的参考点未定义,因此只有连续调用结果之间的差异才有效 |
以上3个方法返回的单位都是秒,对应地有3个带_ns
返回以纳秒为单位的数字:time_ns()
、perf_counter_ns()
、process_time_ns()
。以下用一个例子来说明计时功能的实现,以及这些方法的不同:
def fibonacci(n):
a, b = 0, 1
while n > 0:
a, b = b, a + b
n -= 1
yield a
a_point_tm = time.time()
a_point_perf = time.perf_counter()
a_point_proc = time.process_time()
result_u = sum([i for i in fibonacci(300)])
time.sleep(10)
result_s = sum([i for i in fibonacci(20)])
print(result_s + result_u)
b_point_tm = time.time()
b_point_perf = time.perf_counter()
b_point_proc = time.process_time()
print('time()计算结果:',b_point_tm-a_point_tm)
print('perf_counter()计算结果:',b_point_perf-a_point_perf)
print('process_time()计算结果:',b_point_proc-a_point_proc)
'''
time()计算结果: 10.003293991088867
perf_counter()计算结果: 10.002807212000334
process_time()计算结果: 0.0
'''
datetime
提供了几种操作日期和时间的数据类型,主要有time
、date
、datetime
、timedelta
、tzinfo
和timezone
等6种数据类型;最后的两个tzinfo
和timezone
和时区有关(tzinfo定义了时区信息的基类),以下内容暂不涉及。
datetime
中,既包含了time
中的数据类型(对应于datetime.datetime
),时间精度是到毫秒级(1 毫秒 = 0.001 秒,而不是ns纳秒级),也有date
数据类型,时间单位到天,和表示一天内某个时间的time
。datetime
库对time
库最主要的扩展体现在表示时间差(时间间隔)的timedelta
类型,使得时间之间可以进行各种运算。
文档中的完整形式是:class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
,所有的参数都是可选的并且默认值为 0。这些参数可以是整数或者浮点数,也可以是正数或者负数。timedelta中只会储存days, seconds, microseconds这3个单位,其余参数都是用这3个基本的单位转化的。
timedelta
对象支持本身类型的对象,以及date
和 datetime
类型对象的计算(date
和 datetime
类型对象之间进行计算,返回的就是一个timedelta
对象)。支持的计算类型如下表:
运算 | 结果 |
---|---|
t1 = t2 + t3 | t2 和 t3 的和 |
t1 = t2 - t3 | t2 减 t3 的差 |
t1 = t2 * i 或 t1 = i * t2 | 乘以一个整数 |
t1 = t2 * f 或 t1 = f * t2 | 乘以一个浮点数,结果会被舍入到 timedelta 最接近的整数倍。 |
f = t2 / t3 | 总时间 t2 除以间隔单位 t3。 返回一个 float 对象。 |
t1 = t2 / f 或 t1 = t2 / i | 除以一个浮点数或整数。 结果会被舍入到 timedelta 最接近的整数倍。 精度使用四舍五偶入奇不入规则。 |
t1 = t2 // i or t1 = t2 // t3 | 取整除,余数部分(如果有的话)将被丢弃 |
t1 = t2 % t3 | 余数为一个 timedelta 对象 |
q, r = divmod(t1, t2) | 通过 : q = t1 // t2 (3) and r = t1 % t2 计算出商和余数。q是一个整数,r是一个 timedelta 对象 |
+t1 | 返回一个相同数值的 timedelta 对象。 |
-t1 | 等价于 timedelta(-t1.days, -t1.seconds, -t1.microseconds), 和 t1* -1. (1)(4) |
abs(t) | 当 t.days >= 0`时等于 +t, 当t.days < 0 时 -t |
str(t) | 返回一个形如 [D day[s], ][H]H:MM:SS[.UUUUUU] 的字符串,当 t 为负数的时候, D 也为负数 |
repr(t) | 返回一个 timedelta 对象的字符串表示形式,作为附带正规属性值的构造器调用 |
以计算前一天为例,可以用当天时间直接减去一个timedelta
对象就行(注意timedelta
实例化时,其中的参数都是带“s”的,如days):
import datetime
td = datetime.datetime.now() # datetime.datetime(2019, 9, 26, 21, 58, 21, 151638)
ys = td - datetime.timedelta(days=1) # datetime.datetime(2019, 9, 25, 21, 57, 46, 737021)
ys_p = ys.strftime('%Y-%m-%d %H:%M:%S') # '2019-09-25 22:03:23'
两个时间对象计算后,得到的结果也是timedelta
:
import datetime
td = datetime.datetime.now() # datetime.datetime(2019, 9, 26, 21, 58, 21, 151638)
bth = datetime.datetime(2019,1,11, 15, 10, 40, 96)
result = td - bth # datetime.timedelta(days=258, seconds=25307, microseconds=701024)
timedelta有一个实例方法timedelta.total_seconds()
,返回时间间隔包含了多少秒。
td = datetime.datetime.today()
yd = datetime.datetime(2010,10,31)
dlt = td - yd
print(dlt.total_seconds()) # 282050531.447931
datetime.date
包含3个实例属性:year, month, day;以及3个类属性:date.min(date(MINYEAR, 1, 1)
)、date.max(date(MAXYEAR, 12, 31)
)和date.resolution(两个日期对象的最小间隔,timedelta(days=1)
),返回的格式为year-month-day;datetime.date
类有5种构造方式,最基本的构造函数是__new__(year, month, day)
import datetime
import time
td = datetime.date(2019, 9, 18)
print(td) # 2019-09-18
tdr = datetime.date.today()
print(tdr) # 2019-09-18
td_ts = datetime.date.fromtimestamp(time.time())
print(td_ts) # 2019-09-18
td_d = datetime.date.fromordinal(737320) # 传入一个正整数n,为自公元元年1月1日开始的第n天,例如1为公元1年1月1日
print(td_d) # 2019-09-18
td_iso = datetime.date.fromisoformat('2019-09-18')
print(td_iso) # 2019-09-18
当构造了一个datetime.date
对象后,这个对象就有了year, month, day这3个实例属性,可以通过对象.year
类似的形式访问(也可以通过对象.__getattribute__('year')
来实现)。
datetime.date
对象的实例方法主要有3类:日期参数替换、日期表示、日期的日历信息。日期参数替换的方法是date.replace(year=self.year, month=self.month, day=self.day)
,这个方法可以用来替换实例属性中的值:
td = datetime.date.today() # datetime.date(2019, 10, 8)
rd = td.replace(year=2018, day=1)
print(rd) # 2018-10-01,返回的对象仍是datetime.date类型
日期的表示和日历信息相关的实例方法,可以与前面构造方法的部分对比来看,例如isoformat()可以看做是fromisoformat()的对用函数,toordinal()是fromordinal()的对应函数等。
日期表示的方法主要有时间元组和字符串两种,表示为时间元组的是date.timetuple()
,返回的是与time.localtime()
相同类型的结构体时间(时间元组):
std = datetime.date(2018, 10, 11)
print(std.timetuple())
# time.struct_time(tm_year=2018, tm_mon=10, tm_mday=11,
# tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=284, tm_isdst=-1)
日期的字符串表示,可以使用date.isoformat()
(或date.__str__()
)表示为标准的字符串形式,以及date.ctime()
表示为代表日期的字符串,还包括使用date.strftime(format)
(或date.__format__(format)
),这三种表示方式可以参看以下示例:
rd = datetime.date(2018, 5, 23)
print(rd.isoformat()) # 2018-05-23
print(str(rd)) # 2018-05-23
print(rd.ctime()) # Wed May 23 00:00:00 2018
print(rd.strftime('%Y_%m_%d')) # 2018_05_23
print(rd.__format__('%Y-%m-%d')) # 2018-05-23
日期的日历信息,主要包括日期的星期信息,日历位置信息,和格列高利历序号(即以公元1年1月1日为第1天的序号)。星期信息有两种表示方式:date.weekday()
和date.isoweekday()
,区别是weekday()中星期一用“0”表示(周日是“6”),isoweekday()中星期一用“1”表示(周日是“7”),返回的是数字(int)。
rd = datetime.date(2018, 5, 23)
print(rd.weekday()) # 2
print(rd.isoweekday()) # 3
date.isocalendar()
返回一个三元组:(ISO year, ISO week number, ISO weekday) ,其中ISO是国际标准的意思,文档中举了一个例子可以作为说明:“2004 年的第一天是一个星期四,因此 ISO 2004 年的第一个星期开始于 2003 年 12 月 29 日星期一,结束于 2004 年 1 月 4 日星期日,因此
date(2003, 12, 29).isocalendar() == (2004, 1, 1) and date(2004, 1, 4).isocalendar() == (2004, 1, 7)
”
rd = datetime.date(2018, 5, 23)
print(rd.isocalendar()) # (2018, 21, 3)
除此之外,datetime.date
也支持比较运算(类似地,以下提到的datetime.time
和datetime.datetime
也支持):
lt = datetime.date(2019, 10, 9)
rt = datetime.date(2018, 10, 8)
lt > rt # True
lt >= rt # True
lt == rt # False
datetime.time
表示一天中的某个时间点(不包含日期信息),包含6个实例属性:hour、minute、second、microsecond、tzinfo和fold,最后一个fold的含义是“用于在重复的时间段中消除边界时间歧义”,取值为0或1(默认为0)。除了直接通过赋值实例化之外,datetime.time
还有一个构造方法time.fromisoformat(time_string)
,但文档提示这个方式只是time.isoformat()
的逆操作,并不能解析所有格式的ISO时间字符串。
实例方法中,除了与时区相关的操作外,与前面datetime.date
类似,也有time.isoformat(timespec='auto')
,time.strftime(format)
和time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)
方法,详见文档。
datetime.time
是包含了datetime.date
和datetime.time
所有信息的数据类型,包含9个实例属性:year、month、day、hour、minute、second、microsecond、tzinfo和fold。
datetime.datetime
数据类型的实例化(构造方法)有很多:
import time
import datetime
# 传入参数进行构造
td = datetime.datetime(2019, 10, 8) # datetime.datetime(2019, 10, 8, 0, 0)
# 表示当前时间,带utc的为标准时间,其余为本地时间
td = datetime.datetime.today() # datetime.datetime(2019, 10, 8, 15, 17, 11, 410101)
td = datetime.datetime.now() # datetime.datetime(2019, 10, 8, 15, 17, 11, 410101)
td = datetime.datetime.utcnow() # datetime.datetime(2019, 10, 8, 7, 18, 44, 10496)
# 传入时间戳,带utc的为标准时间,其余为本地时间
td = datetime.datetime.fromtimestamp(time.time()) # datetime.datetime(2019, 10, 8, 15, 20, 36, 362426)
td = datetime.datetime.utcfromtimestamp(time.time()) # datetime.datetime(2019, 10, 8, 7, 22, 5, 428847)
# 传入格列高利历序号(即公元1年1月1日起的第几天)
td = datetime.datetime.fromordinal(737340) # datetime.datetime(2019, 10, 8, 0, 0)
# 传入标准的时间字符串
td = datetime.datetime.fromisoformat('2019-10-08 15:25:23') # datetime.datetime(2019, 10, 8, 15, 25, 23)
# 合并日期和时间的数据
td = datetime.datetime.combine(datetime.date.today(), datetime.time(12, 5, 34)) # datetime.datetime(2019, 10, 8, 12, 5, 34)fold
# 字符串序列化
td = datetime.datetime.strptime('2019-10-08 15:25:23', '%Y-%m-%d %H:%M:%S') # datetime.datetime(2019, 10, 8, 15, 25, 23)
datetime.datetime
有min、max、resolution等3个类方法,以及year、month、day、hour、minute、second、microsecond、tzinfo和fold等9个实例方法:
datetime.datetime.resolution # datetime.timedelta(microseconds=1)
td = datetime.datetime.now() # datetime.datetime(2019, 10, 8, 22, 35, 24, 199131)
td.day # 8
datetime.datetime
的实例方法主要有3类:参数替换、时间表示(以及表示方式的转换)、时间的日历信息以及时区操作等4类。
参数替换的方法是datetime.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)
。
时间表示的相关方法中,
datetime.date()
和datetime.time()
用于将datetime.datetime
对象转换为datetime.date
或datetime.time
类型的对象;datetime.timetuple()
和datetime.utctimetuple()
可以将datetime.datetime
对象转换为时间元组格式;datetime.toordinal()
会返回日期的预期格列高利历序号;datetime.timestamp()
会返回时间戳;datetime.isoformat()
会返回一个标准的时间戳(ISO 8601 格式表示日期和时间的字符串 YYYY-MM-DDTHH:MM:SS.ffffff);datetime.ctime()
返回一个表示时间的字符串datetime.strftime(format)
返回一个由显式格式字符串所指明的代表日期和时间的字符串:td = datetime.datetime.now() # datetime.datetime(2019, 10, 8, 23, 10, 4, 243267)
td.date() # datetime.date(2019, 10, 8)
td.time() #datetime.time(23, 10, 4, 243267)
td.timetuple() # time.struct_time(tm_year=2019, tm_mon=10,
# tm_mday=8, tm_hour=23, tm_min=10, tm_sec=53, tm_wday=1, tm_yday=281, tm_isdst=-1)
td.toordinal() # 737340
td.timestamp() # 1570547527.534725
td.isoformat() # '2019-10-08T23:14:17.739123'
td.ctime() # 'Tue Oct 8 23:16:56 2019'
td.strftime('%Y-%m-%d %H-%M-%S') # '2019-10-08 23-19-02'
此外与datetime.date
中相同,datetime.datetime
也提供了关于日历信息的方法,主要有以下3个:
td = datetime.datetime.fromisoformat('2019-10-08 15:25:23')
td.weekday() # 1
td.isoweekday() # 2
td.isocalendar() # (2019, 41, 2)
calendar
定义了一些日历相关的数据类型,并基于此提供了一系列操作日期的相关函数。默认情况下,这些日历(数据类型)把星期一当作一周的第一天,星期天为一周的最后一天(按照欧洲惯例)。
calendar
主要由类Calendar、Calendar一些子类(TextCalendar,HTMLCalendar以及这两个类的子类)以及一些方法构成。最基本的用法是通过calendar.calendar(year, w=2, l=1, c=6, m=3)
方法来实例化一个日历:
import calendar
cld = calendar.calendar(2019)
print(cld)
'''
2019
January February March
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 1 2 3 1 2 3
7 8 9 10 11 12 13 4 5 6 7 8 9 10 4 5 6 7 8 9 10
14 15 16 17 18 19 20 11 12 13 14 15 16 17 11 12 13 14 15 16 17
21 22 23 24 25 26 27 18 19 20 21 22 23 24 18 19 20 21 22 23 24
28 29 30 31 25 26 27 28 25 26 27 28 29 30 31
April May June
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7 1 2 3 4 5 1 2
8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9
15 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16
22 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23
29 30 27 28 29 30 31 24 25 26 27 28 29 30
July August September
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7 1 2 3 4 1
8 9 10 11 12 13 14 5 6 7 8 9 10 11 2 3 4 5 6 7 8
15 16 17 18 19 20 21 12 13 14 15 16 17 18 9 10 11 12 13 14 15
22 23 24 25 26 27 28 19 20 21 22 23 24 25 16 17 18 19 20 21 22
29 30 31 26 27 28 29 30 31 23 24 25 26 27 28 29
30
October November December
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 1 2 3 1
7 8 9 10 11 12 13 4 5 6 7 8 9 10 2 3 4 5 6 7 8
14 15 16 17 18 19 20 11 12 13 14 15 16 17 9 10 11 12 13 14 15
21 22 23 24 25 26 27 18 19 20 21 22 23 24 16 17 18 19 20 21 22
28 29 30 31 25 26 27 28 29 30 23 24 25 26 27 28 29
30 31
'''
calendar.calendar(year, w=2, l=1, c=6, m=3)
,根据文档的说明,是“使用 TextCalendar 类的 formatyear() 返回整年的3列的日历以多行字符串的形式”,可选参数 w, l, 和 c 分别表示日期列数, 周的行数, 和月之间的间隔。
这相当于:
cld = calendar.TextCalendar()
result = cld.formatyear(2019)
print(result)
可以通过calendar.setfirstweekday(weekday)
来指定一周的开始(0表示星期一,6表示星期天):
calendar.setfirstweekday(6)
cld = calendar.calendar(2019)
print(cld)
'''
2019
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 1 2 1 2
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23
27 28 29 30 31 24 25 26 27 28 24 25 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 2 3 4 5 6 1 2 3 4 1
7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
28 29 30 26 27 28 29 30 31 23 24 25 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 3 4 5 6 1 2 3 1 2 3 4 5 6 7
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28
28 29 30 31 25 26 27 28 29 30 31 29 30
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 1 2 1 2 3 4 5 6 7
6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
'''
类似地,calendar
提供了calendar.monthcalendar(year, month)
方法,输出某个月的日历,也可以通过calendar.prcal(year, w=0, l=0, c=6, m=3)
和calendar.prmonth(theyear, themonth, w=0, l=0)
直接打印出日历或月历。
除了纯文本意外的另一种输出形式是html格式(默认参数可以参考之前列出的,这是一个没有边框线的月历):
cld = calendar.HTMLCalendar()
result = cld.formatmonth(2019,10)
print(result)
'''
October 2019
Mon Tue Wed Thu Fri Sat Sun
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.isleap(year)
判断这个年份是否是闰年;calendar.leapdays(y1, y2)
返回两个年份之间闰年的数量:
calendar.isleap(2019) # False
calendar.leapdays(2010,2019) # 2
calendar.weekday(year, month, day)
可以判断某个日期是星期几,返回一个数字(0代表星期一):
calendar.weekday(-101,11,2) # 3
calendar.timegm(tuple)
被文档称为“一个不相关但很好用的函数”(an unrelated but handy function),“它接收一个时间元组例如 time 模块中的 gmtime() 函数的返回并返回相应的 Unix 时间戳,假定 1970 年开始计数”,可以与time模块的time.mktime()
对比:
import time
import datetime
import calendar
dy = datetime.date(2018, 11, 1)
dytuple = dy.timetuple()
res_a = calendar.timegm(dytuple)
res_b = time.mktime(dytuple)
print(res_a) # 1541030400,这是基于标准时间的结果
print(res_b) # 1541001600.0,这是基于本地时间的结果