Python3 中的时间与日期模块详解

Python 中不包含表示日期和时间的基本数据类型,但是提供了如下三个模块用于操作时间日期类型的数据:

  • time:提供与时间相关的功能。包含时钟时间、处理器运行时间、基本的格式化工具等
  • datetime:提供处理时间日期的高级接口。如时间日期之间的算术计算和大小比较等
  • calendar:提供类似日历的年、月、日、周的格式化输出和其他日历相关的功能

一、time

time 模块包含多种类型的“时钟”时间,方便处理多种不同需求的任务。如:

  • time() 返回自纪年以来的秒数。纪年指 time.gmtime(0) 函数的返回值,大多数系统中是 1970年1月1日00:00:00(UTC)
  • monotonic() 可以用来测量长时间运行的进程,它不会因为系统时间被修改而发生变化
  • perf_counter() 提供了精度最高的时间量度,因此多用于获取短时间段的高精度结果
  • process_time() 返回当前进程中系统和用户 CPU 时间的总和。不包括 sleep() 时间

测试程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import textwrap
import time

available_clocks = [
('time', time.time),
('monotonic', time.monotonic),
('perf_counter', time.perf_counter),
('process_time', time.process_time),
]

for clock_name, func in available_clocks:
print(textwrap.dedent('''\
{name}:
adjustable : {info.adjustable}
implementation: {info.implementation}
monotonic : {info.monotonic}
resolution : {info.resolution}
result : {result}
''').format(
name=clock_name,
info=time.get_clock_info(clock_name),
result=func())
)

输出中包含了各时钟函数的实现方式、精度和执行结果等:

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
time:
adjustable : True
implementation: clock_gettime(CLOCK_REALTIME)
monotonic : False
resolution : 1e-09
result : 1576935284.1307783

monotonic:
adjustable : False
implementation: clock_gettime(CLOCK_MONOTONIC)
monotonic : True
resolution : 1e-09
result : 1653915.765674168

perf_counter:
adjustable : False
implementation: clock_gettime(CLOCK_MONOTONIC)
monotonic : True
resolution : 1e-09
result : 1653915.765707337

process_time:
adjustable : False
implementation: clock_gettime(CLOCK_PROCESS_CPUTIME_ID)
monotonic : True
resolution : 1e-09
result : 0.017164144

上述几个时钟函数中,只有 time.time() 在计算时间时有明确的参考点(time.gmtime(0)),另外三个函数都没有定义绝对的起点作为基准,因此常用来计算某个过程耗费的时间总和(多次执行并计算时间差),而无法获取一个标准的绝对时间。

1
2
3
4
>>> start = time.perf_counter()
>>> end = time.perf_counter()
>>> end - start
8.590425299999993

上述函数返回的都是以秒为单位精度较高的浮点数。对于需要记录或者打印方便阅读的时间日期时,可以使用 ctime() 函数:

1
2
3
4
5
>>> time.ctime()
'Sat Dec 21 21:56:41 2019'
>>> later = time.time() + 30
>>> time.ctime(later)
'Sat Dec 21 21:57:19 2019'

time 模块中还定义了 struct_time 结构用来表示日期和时间中的每一项独立的值(年月日、时分秒等)。

1
2
3
4
5
6
7
>>> loc_time = time.localtime()
>>> loc_time
time.struct_time(tm_year=2019, tm_mon=12, tm_mday=21, tm_hour=22, tm_min=20, tm_sec=32, tm_wday=5, tm_yday=355, tm_isdst=0)
>>> loc_time.tm_year
2019
>>> loc_time.tm_hour
22

时间的格式化输出

strftime() 函数可以用来将 struct_time 格式的时间值转换为字符串的形式表示。strptime() 函数的行为则相反。如:

1
2
3
4
5
6
7
8
9
10
11
>>> import time
>>> loc_time = time.localtime()
>>> loc_time
time.struct_time(tm_year=2019, tm_mon=12, tm_mday=21, tm_hour=23, tm_min=21, tm_sec=33, tm_wday=5, tm_yday=355, tm_isdst=0)
>>> time.strftime('%Y-%m-%d %H:%M:%S', loc_time)
'2019-12-21 23:21:33'
>>> now = time.ctime()
>>> now
'Sat Dec 21 23:23:31 2019'
>>> time.strptime(now)
time.struct_time(tm_year=2019, tm_mon=12, tm_mday=21, tm_hour=23, tm_min=23, tm_sec=31, tm_wday=5, tm_yday=355, tm_isdst=-1)

常见的字符串形式的时间日期格式如下:

1
2
3
4
>>> time.strftime('%Y-%m-%d %H:%M:%S')
'2019-12-21 23:26:40'
>>> time.strftime('%a %b %d %H:%M:%S %Y')
'Sat Dec 21 23:27:15 2019'

strftime() 函数支持的更多格式定义可参考 help(time.strftime)

二、datetime

datetime 模块中定义的函数和类可以对日期和时间进行转换、格式化输出、算术计算等操作。

time

time 类可以表示包含时、分、秒、时区等信息的时间对象。

1
2
3
4
5
6
7
8
9
10
11
12
>>> import datetime
>>> t = datetime.time(1, 2, 3)
>>> print(t)
01:02:03
>>> t.hour
1
>>> t.minute
2
>>> t.second
3
>>> t.tzinfo
>>>

date

date 类可以表示包含年、月、日等信息的日期值。其 today() 方法可以获取当天的日期。

1
2
3
4
5
6
7
8
9
10
>>> from datetime import date
>>> today = date.today()
>>> today
datetime.date(2019, 12, 21)
>>> today.year
2019
>>> today.month
12
>>> today.day
21

datetime

datetime 模块中的 datetime 类可以表示完整的日期和时间,类似 time 类和 date 类的结合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2019, 12, 22, 0, 30, 21, 372631)
>>> print(now)
2019-12-22 00:30:21.372631
>>> t = datetime.time(1, 2, 3)
>>> print(t)
01:02:03
>>> d = datetime.date.today()
>>> print(d)
2019-12-22
>>> dt = datetime.datetime.combine(d, t)
>>> dt
datetime.datetime(2019, 12, 22, 1, 2, 3)
>>> print(dt)
2019-12-22 01:02:03

timedelta

timedelta 类可以表示某个特定长度的时间段(以年月日或时分秒等为单位)。
两个 datetime 相减会得到 timedelta 对象,也可以用 datetime 加上或者减去 timedelta 得到新的时间值。

日期加减:

1
2
3
4
5
6
7
8
9
>>> import datetime
>>> today = datetime.date.today()
>>> today
datetime.date(2019, 12, 22)
>>> twodays = datetime.timedelta(days=2)
>>> print(twodays)
2 days, 0:00:00
>>> today - twodays
datetime.date(2019, 12, 20)

时间加减:

1
2
3
4
5
6
7
8
9
10
11
>>> import datetime
>>> now = datetime.datetime.now()
>>> print(now)
2019-12-22 00:35:30.298198
>>> delta = datetime.timedelta(days=1, minutes=30)
>>> print(delta)
1 day, 0:30:00
>>> now - delta
datetime.datetime(2019, 12, 21, 0, 5, 30, 298198)
>>> print(now - delta)
2019-12-21 00:05:30.298198

比较大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> t1 = datetime.time(12, 30, 20)
>>> print(t1)
12:30:20
>>> t2 = datetime.time(11, 20, 40)
>>> print(t2)
11:20:40
>>> t2 > t1
False
>>> today = datetime.date.today()
>>> print(today)
2019-12-22
>>> tomorrow = today + datetime.timedelta(days=1)
>>> print(tomorrow)
2019-12-23
>>> today < tomorrow
True
格式化输出

datetime 类中也提供了 strftimestrptime 方法,使用示例如下:

1
2
3
4
5
6
7
8
9
10
>>> import datetime
>>> format = "%a %b %d %H:%M:%S %Y"
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2019, 12, 22, 1, 7, 53, 505983)
>>> s = now.strftime(format)
>>> s
'Sun Dec 22 01:07:53 2019'
>>> datetime.datetime.strptime(s, format)
datetime.datetime(2019, 12, 22, 1, 7, 53)

三、calendar

这部分的功能目前还没用到,简单示例如下:

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
>>> import calendar
>>> c = calendar.TextCalendar(calendar.SUNDAY)
>>> c.prmonth(2019, 12)
December 2019
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
>>> cal = calendar.TextCalendar(calendar.SUNDAY)
>>> print(cal.formatyear(2020, 2, 1, 1, 3))
2020

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 1 1 2 3 4 5 6 7
5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14
12 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21
19 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28
26 27 28 29 30 31 23 24 25 26 27 28 29 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 1 2 1 2 3 4 5 6
5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
26 27 28 29 30 24 25 26 27 28 29 30 28 29 30
31
...

参考资料

THE PYTHON 3 STANDARD LIBRARY BY EXAMPLE