一、问题背景
最近有小伙伴反馈接口平台的测试计划执行耗时显示有误,比如执行实际时长超过10s,但是报告中显示总耗时小于1s
显示耗时统计出现问题
二、问题排查
开始和结束时间是否有误
开始时间:
2022-04-24 10:51:23.677632
结束时间:
2022-04-24 10:51:35.713161
可见起止的时间获取没有问题
计算方式
round((end_time-start_time).microseconds/1000000, 2)
计算结果0.04s
接下来看看为什么这样的计算方式出错
三、datetime
datetime模块可以生成所需日期和时间的字符串,还可以进行时间差计算
3.1 时间差计算
import datetime
datetime.datetime.now()
# 生成一个datetime.datetime对象,包含了年、月、日、时、分、秒、毫秒七个参数
# 可以直接获取年、月、日等数值:
t = datetime.datetime.now()
print(t.year, t.month, t.day, t.hour, t.minute, t.second, t.microsecond)
print(type(t.year), type(t.month), type(t.day), type(t.hour), type(t.minute), type(t.second), type(t.microsecond))
# output:
2022 4 24 11 3 25 336771
<class 'int'> <class 'int'> <class 'int'> <class 'int'> <class 'int'> <class 'int'> <class 'int'>
3.2 时间和日期的获取
# 可以分别获得日期,时间:
print(t.date(), type(t.date()))
print(t.time(), type(t.time()))
# output:
2022-04-24 <class 'datetime.date'>
11:06:50.314211 <class 'datetime.time'>
3.3 格式化输出字符串
可以按照需要格式化输出字符串:datetime.datetime.strftime("format")
指令 | 意义 | 示例 |
---|---|---|
%a | 当地工作日的缩写 | Sun, Mon, …, Sat |
%A | 当地工作日的全名 | Sunday, Monday, …, Saturday |
%w | 以十进制数显示的工作日,其中0表示星期日,6表示星期六 | 0, 1, …, 6 |
%d | 补零后,以十进制数显示的月份中的一天 | 01, 02, …, 31 |
%b | 当地月份的缩写 | an, Feb, …, Dec |
%B | 当地月份的全名 | January, February, …, December |
%m | 补零后,以十进制数显示的月份 | 01, 02, …, 12 |
%y | 补零后,以十进制数表示的,不带世纪的年份 | 00, 01, …, 99 |
%Y | 十进制数表示的带世纪的年份 | 0001, 0002, …, 2013, 2014, …, 9998, 9999 |
%H | Hour (24-hour clock) | 00, 01, …, 23 |
%I | Hour (12-hour clock) | 01, 02, …, 12 |
%M | 补零后,以十进制数显示的分钟 | 00, 01, …, 59 |
%S | 补零后,以十进制数显示的秒 | 00, 01, …, 59 |
%U | Week number of the year (Sunday as the first day of the week) | 00, 01, …, 53 |
%W | Week number of the year (Monday as the first day of the week) | 00, 01, …, 53 |
%c | 本地化的适当日期和时间表示 | Tue Aug 16 21:30:00 1988 |
%x | 本地化的适当日期表示 | 08/16/1988 |
%X | 本地化的适当时间表示 | 21:30:00 |
%% | 字面的 ‘%’ 字符 | 字面的 ‘%’ 字符 |
格式可以用任意连接符组合成你想要的格式
import datetime
t = datetime.datetime.now()
print(t.strftime("%Y%m%d"),type(t.strftime("%Y%m%d")))
print(t.strftime("%Y-%m_%d:%H-%M:%S"))
# output:
20220424 <class 'str'>
2022-04_24:11-16:36
注意,此时返回的就是字符串
datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
通过datetime.timedelta类创建一个时间差,用来进行计算
四、问题解决
通过datetime
的使用可以看到,(end_time-start_time).microseconds
获取的是毫秒这个维度的值,而非所有的值
import datetime
# 2022-04-24 10:51:23.677632
start_time = datetime.datetime(2022, 4, 24, 10, 51, 23, 677632)
# 2022-04-24 10:51:35.713161
end_time = datetime.datetime(2022, 4, 24, 10, 51, 35, 713161)
print("days: ", (end_time-start_time).days)
print("seconds: ", (end_time-start_time).seconds)
print("microseconds: ", (end_time-start_time).microseconds)
# output:
days: 0
seconds: 12
microseconds: 35529
如果想要获取秒级时间差,而且保留2位小数,可以
(end_time-start_time).seconds + round((end_time-start_time).microseconds/1000000, 2)
也可以使用total_seconds()方法
round((end_time-start_time).total_seconds(), 2)
问题解决
五、秒数间隔
datetime计算秒数间隔
import datetime
# 2022-04-24 10:51:23.677632
start_time = datetime.datetime(2022, 4, 24, 10, 51, 23, 677632)
# 2022-04-25 11:52:35.713161
end_time = datetime.datetime(2022, 4, 25, 11, 52, 35, 713161)
print("seconds: ", (end_time-start_time).seconds)
# output:
seconds: 3672
这两个时间相差1d+,但是输出的结果中仅为3672s
原因在于seconds只能计算同一天的间隔,所以事先要计算出差值的天数,用天数144060+秒数才能得到正确的结果
对于这种情况一般使用total_seconds()来解决
import datetime
# 2022-04-24 10:51:23.677632
start_time = datetime.datetime(2022, 4, 24, 10, 51, 23, 677632)
# 2022-04-25 11:52:35.713161
end_time = datetime.datetime(2022, 4, 25, 11, 52, 35, 713161)
print((end_time-start_time).total_seconds())
# output:
total_seconds: 90072.035529