time时间模块
time时间模块
目录
- time时间模块
- 1.概述
- 2.查看不同类型的时钟
- 3.墙上时钟time
- 3.1.time()当前时间戳
- 3.2.ctime()格式化时间
- 4.单调时钟计算测量时间
- 5.cpu处理器时钟时间
- 6.性能计数器
- 7.时间组成
- 8.处理时区
- 9.解析和格式化时间
1.概述
time模块允许访问多种类型的时钟,分别用于不同的用途。
标准系统调用time()会报告系统“墙上时钟”
monotonic()时钟可以用于测量一个长时间运行的进程的耗用时间,因为及时系统时间没有变,也能保证这个时间不会逆转。
perf_counter(()允许访问有最高可用分辨率的时钟,这使得短时间测量更准确
2.查看不同类型的时钟
使用get_clock_info()可以获得当前平台下实现的时钟信息。
import textwrap
import timeavailable_clocks = [('monotonic', time.monotonic),('perf_counter', time.perf_counter),('process_time', time.process_time),('time', time.time),
]for clock_name, func in available_clocks:print(textwrap.dedent('''\{name}:adjustable : {info.adjustable}implementation: {info.implementation}monotonic : {info.monotonic}resolution : {info.resolution}current : {current}''').format(name=clock_name,info=time.get_clock_info(clock_name),current=func()))
运行上面的代码分别查看不同类型时钟信息
monotonic:adjustable : Falseimplementation: mach_absolute_time()monotonic : Trueresolution : 1e-09current : 897155.360871048perf_counter:adjustable : Falseimplementation: mach_absolute_time()monotonic : Trueresolution : 1e-09current : 897155.36094208process_time:adjustable : Falseimplementation: clock_gettime(CLOCK_PROCESS_CPUTIME_ID)monotonic : Trueresolution : 1.0000000000000002e-06current : 0.037212time:adjustable : Trueimplementation: clock_gettime(CLOCK_REALTIME)monotonic : Falseresolution : 1.0000000000000002e-06current : 1675936487.1994529
3.墙上时钟time
time模块的核心函数之一就是time,他会把从“纪元”开始以来的秒数作为一个浮点值返回。纪元是时间测量的起始点,对于UNIX系统这个起始时间就是1970年1月1日0:00 尽管这个值总是一个浮点数,但具体的精度依赖于具体的平台。
3.1.time()当前时间戳
下面调用time()函数打印出当前时间戳
import timeprint('The time is:', time.time())
3.2.ctime()格式化时间
time()输出了当前时间的时间戳,对于人类而言可读性不好,使用ctime()获取格式化的时间。
import timeprint('The time is :', time.ctime())
later = time.time() + 15
print('15 secs from now :', time.ctime(later))
运行上面代码
The time is : Thu Feb 9 19:09:26 2023
15 secs from now : Thu Feb 9 19:09:41 2023
4.单调时钟计算测量时间
由于time()查看系统时钟,并且用户或系统服务可能改变时钟同步其他计算机时钟,所以反复调用time()所产生的值可能会前后浮动。
如果用来测量持续时间,可能会导致意向不到的行为。为了避免这种情况可以使用monotonic(),它总是返回向前的值。
单调时钟的起始点没有被定义,所以返回值只是在与其他时钟值完成计算时有用。
下面的例子使用monotonic()测量睡眠持续时间,
import timestart = time.monotonic()
time.sleep(0.1)
end = time.monotonic()
print('start : {:>9.2f}'.format(start))
print('end : {:>9.2f}'.format(end))
print('span : {:>9.2f}'.format(end - start))
运行代码,输出测量的时间。
start : 902018.64
end : 902018.74
span : 0.10
5.cpu处理器时钟时间
time()返回的是一个墙上时钟时间,而clock()返回处理器时钟时间。返回的值反应了程序运行时使用的实际时间。一般情况下,如果程序什么也没有做,处理器时钟不会改变。
import hashlib
import time# Data to use to calculate md5 checksums
data = open(__file__, 'rb').read()for i in range(5):h = hashlib.sha1()print(time.ctime(), ': {:0.3f} {:0.3f}'.format(time.time(), time.process_time()))for i in range(300000):h.update(data)cksum = h.digest()
运行上面的代码,输出cpu时钟时间
Thu Feb 9 19:27:35 2023 : 1675942055.033 0.043
Thu Feb 9 19:27:35 2023 : 1675942055.395 0.401
Thu Feb 9 19:27:35 2023 : 1675942055.768 0.766
Thu Feb 9 19:27:36 2023 : 1675942056.123 1.117
Thu Feb 9 19:27:36 2023 : 1675942056.472 1.463
下面这个例子中,循环几乎不做什么工作,每次迭代后都会睡眠。在应用睡眠时,time()值会增加,而clock()值不会增加。
import timetemplate = '{} - {:0.2f} - {:0.2f}'print(template.format(time.ctime(), time.time(), time.process_time())
)for i in range(3, 0, -1):print('Sleeping', i)time.sleep(i)print(template.format(time.ctime(), time.time(), time.process_time()))
运行上面的代码,进程sleep休眠时不会占用cpu资源,因此cpu的时间不会改变。
Thu Feb 9 19:40:18 2023 - 1675942818.83 - 2.36
Sleeping 3
Thu Feb 9 19:40:21 2023 - 1675942821.84 - 2.36
Sleeping 2
Thu Feb 9 19:40:23 2023 - 1675942823.84 - 2.36
Sleeping 1
Thu Feb 9 19:40:24 2023 - 1675942824.84 - 2.36
6.性能计数器
在测量性能时,高分辨率时钟是必不可少的。python通过perf_counter()提供精确计算。perf_counter()的纪元未定义,所以返回值只用于比较和计算值,而不作为绝对时间。
import hashlib
import time# Data to use to calculate md5 checksums
data = open(__file__, 'rb').read()loop_start = time.perf_counter()for i in range(5):iter_start = time.perf_counter()h = hashlib.sha1()for i in range(300000):h.update(data)cksum = h.digest()now = time.perf_counter()loop_elapsed = now - loop_startiter_elapsed = now - iter_startprint(time.ctime(), ': {:0.3f} {:0.3f}'.format(iter_elapsed, loop_elapsed))
运行结果
Thu Feb 9 19:49:34 2023 : 0.252 0.252
Thu Feb 9 19:49:35 2023 : 0.281 0.533
Thu Feb 9 19:49:35 2023 : 0.266 0.799
Thu Feb 9 19:49:35 2023 : 0.245 1.044
Thu Feb 9 19:49:35 2023 : 0.252 1.296
7.时间组成
有些情况需要访问一个日期的各个字段,例如年和月。time模块定义了struct_time来保存日期和时间,分解了各个部分便于访问。
gmtime()函数已UTC格式返回当前时间
localtime()将时区考虑在内了,转出的当前时区的时间
mktime()取一个struct_time实例,将它转换为浮点数
import timedef show_struct(s):print(' tm_year :', s.tm_year)print(' tm_mon :', s.tm_mon)print(' tm_mday :', s.tm_mday)print(' tm_hour :', s.tm_hour)print(' tm_min :', s.tm_min)print(' tm_sec :', s.tm_sec)print(' tm_wday :', s.tm_wday)print(' tm_yday :', s.tm_yday)print(' tm_isdst:', s.tm_isdst)print('gmtime:')
show_struct(time.gmtime())
print('\nlocaltime:')
show_struct(time.localtime())
print('\nmktime:', time.mktime(time.localtime()))
运行结果中gmtime输出的时间是UTC时间,localtime输出的是当前时区的时间。
gmtime:tm_year : 2023tm_mon : 2tm_mday : 9tm_hour : 12tm_min : 6tm_sec : 34tm_wday : 3tm_yday : 40tm_isdst: 0localtime:tm_year : 2023tm_mon : 2tm_mday : 9tm_hour : 20tm_min : 6tm_sec : 34tm_wday : 3tm_yday : 40tm_isdst: 0mktime: 1675944394.0
8.处理时区
修改时区不会改变具体的时间,只会改变表示时间的方式。要改变时区,需要设置环境变量TZ,然后调用tzset()。设置时区可以指定很多细节,通常更容易的做法是使用时区名,由底层库推导出其他信息。
下面这个例子将时区修改为一些不同的值,展示这些改变对time模块中其他设置影响
import time
import osdef show_zone_info():print(' TZ :', os.environ.get('TZ', '(not set)'))print(' tzname:', time.tzname)print(' Zone : {} ({})'.format(time.timezone, (time.timezone / 3600)))print(' DST :', time.daylight)print(' Time :', time.ctime())print()print('Default :')
show_zone_info()ZONES = ['GMT','Europe/Amsterdam',
]for zone in ZONES:os.environ['TZ'] = zonetime.tzset()print(zone, ':')show_zone_info()
输出结果
Default :TZ : (not set)tzname: ('CST', 'CST')Zone : -28800 (-8.0)DST : 0Time : Thu Feb 9 20:24:08 2023GMT :TZ : GMTtzname: ('GMT', 'GMT')Zone : 0 (0.0)DST : 0Time : Thu Feb 9 12:24:08 2023Europe/Amsterdam :TZ : Europe/Amsterdamtzname: ('CET', 'CEST')Zone : -3600 (-1.0)DST : 1Time : Thu Feb 9 13:24:08 2023
9.解析和格式化时间
strftime() 和 strptime()的功能正好相反, 实现字符串和时间元组的相互转换。
-
strptime()中的p指的是parse, 意思是解析, 一般解析都是说对字符串进行解析, 所以strptime()方法的作用是将字符串解析为时间元组
-
strftime()中的f指的是format, 意思是格式化, 也就是处理成适合人看的格式, 所以strftime()方法的作用是将时间元组格式化为字符串
import timedef show_struct(s):print(' tm_year :', s.tm_year)print(' tm_mon :', s.tm_mon)print(' tm_mday :', s.tm_mday)print(' tm_hour :', s.tm_hour)print(' tm_min :', s.tm_min)print(' tm_sec :', s.tm_sec)print(' tm_wday :', s.tm_wday)print(' tm_yday :', s.tm_yday)print(' tm_isdst:', s.tm_isdst)now = time.ctime(1483391847.433716)
print('Now:', now)parsed = time.strptime(now)
print('\nParsed:')
show_struct(parsed)print('\nFormatted:',time.strftime("%a %b %d %H:%M:%S %Y", parsed))
运行结果
Now: Tue Jan 3 05:17:27 2017Parsed:tm_year : 2017tm_mon : 1tm_mday : 3tm_hour : 5tm_min : 17tm_sec : 27tm_wday : 1tm_yday : 3tm_isdst: -1Formatted: Tue Jan 03 05:17:27 2017