【python常用标准库(时间模块time和datetime)】听闻少年二字,当与平庸相斥。这篇文章主要讲述python常用标准库(时间模块time和datetime)相关的知识,希望能为你提供帮助。
常用的标准库
time时间模块import time
time -- 获取本地时间戳时间戳又被称之为是Unix时间戳,原本是在Unix系统中的计时工具。
它的含义是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。UNIX时间戳的 0 按照ISO 8601规范为 :1970-01-01T00:00:00Z。
比如:
- 时间戳 60 表示 1970-01-01T00:01:00Z
- 时间戳 120 表示 1970-01-01T00:02:00Z
- 时间戳 3600 表示 1970-01-01T01:00:00Z
import timestamp_time = time.time()
print(stamp_time)# 1635768368.2838552
localtime -- 获取本地时间元组(UTC)参数为时间戳,默认为本地时间戳,获取时间元组。
时间元组是python中的一个特殊的数据类型
type: time.struct_time
,但是它和tuple
的特性是相同的。import time# 时间元组中的值分别表示:
# tm_year: 年
# tm_mon: 月
# tm_mday: 日
# tm_hour: 时
# tm_min: 分
# tm_sec: 秒
# tm_wday: 周几(0表示星期一)
# tm_yday: 一年中的第几天(从1开始)
# tm_isdst: 夏令标识(1夏令时、0非夏令时、-1未知)# 默认当前时间
time_tuple = time.localtime()
print(time_tuple)
# time.struct_time(tm_year=2021, tm_mon=11, tm_mday=1, tm_hour=20, tm_min=7, tm_sec=50, tm_wday=0, tm_yday=305, tm_isdst=0)# 指定时间戳
time_tuple = time.localtime(3600)
print(time_tuple)
# time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=9, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
gmtime -- 获取时间元组(GMT)在不知道这个函数的时候,我就很好奇为什么
localtime
的初始时间比格林威治时间要快8小时,现在就明白了:函数 | 描述 |
---|---|
gmtime | 获取时间元组(GMT格林威治时间) |
localtime | 获取时间元组(UTC协调世界时) |
- 参数必须是时间元组
time.struct_time
或者元组tuple
类型; - 元组中的元素一个也不能少,必须九个元素都存在;
- 得到的时间戳只收到前六个值的影响,即:年月日时分秒;
- 时间元组中的时间表示,最小时间不能低于当地的最小时间戳;
- 时间元组中的时间表示,单位可以超出原本的范围,比如秒满60进1,我们将秒写成100,系统也不会报错,但是时间上会自动的将多出的时间进位。但是数字也不能过大,因为数据类型的大小是有极限的。
- mktime返回的数值是浮点型的,但是精度只能到1;
import time# 在中国的最小时间单位
tst = (1970, 1, 1, 8, 0, 0, 0, 0, 0)
time_stamp = time.mktime(tst)
print(time_stamp)# 0.0
ctime -- 获取时间字符串参数默认为本地时间戳,获取的数据类型是
str
,这个时间字符串不像时间元组是一个单独的数据类型。import time# 时间字符串中的含义是:
# Mon Nov1 21:34:39 2021
# 星期 月日 时 分 秒年# 默认为本地时间戳
time_char = time.ctime()
print(time_char)# Mon Nov1 21:34:39 2021# 指定时间戳
time_char = time.ctime(0)
print(time_char)# Thu Jan1 08:00:00 1970
asctime -- 时间元组获取时间字符串注意,asctime有弊端,看下例:
import timetst = (1970, 1, 1, 8, 24, 61, 1, 0, 0)
time_char = time.asctime(tst)
print(time_char)# Tue Jan1 08:24:61 1970tst = (1970, 1, 1, 8, 24, 61, 2, 0, 0)
time_char = time.asctime(tst)
print(time_char)# Tue Jan1 08:24:61 1970
看上面的例子,时间元组变成时间字符串的时候,会将星期的数据也读取到,但是却不会分辨数据是否正确,所以asctime并不常用。
如果要将一个不确定正确性的时间元组变成时间字符串的话,先通过
mktime
获取时间戳(mktime可以分辨出正确的时间信息),然后在将时间戳通过 ctime
变成时间字符串。strftime -- 格式化时间格式化时间,按照指定的格式(一段格式化字符串,就像字符串的格式化一样)将时间元组变成时间字符串。
我们先来学习一下时间占位符的含义是什么:
注意!!!这些占位符的大小写的含义是不同的:
占位符 | 含义 |
---|---|
%Y | 以十进制数字表示以世纪为单位的年份(四位数) |
%y | 以十进制数字表示年份(两位数) |
%m | 以十进制数字表示月份 |
%D | 以月/日/年(两位数) 的格式表示年月日 |
%d | 以十进制数字表示日期 |
%H | 以十进制数字表示二十四小时制的时 |
%M | 以十进制数字表示分钟 |
%S | 以十进制数字表示秒 |
%z | 与UTC的时区偏移 |
%a | 区域设置的缩写工作日名称 |
%A | 区域设置的完整工作日名称 |
%b | 区域设置的缩写月份名称 |
%B | 区域设置的完整月份名称 |
%c | 语言环境的适当日期和时间表示 |
%I | 以十进制数表示十二小时制的时(大写 ‘爱’) |
%p | 语言环境的等效值:AM 或者 PM |
import time# 注意,如果格式化字符串中出现中文字符,只能在linux系统下运行,windows下不能解析,直接报错。tst = (1970, 1, 1, 8, 0, 0, 0, 0, 0)
time_tuple = time.strftime(%Y-%m-%d-%H-%m-%S,tst)
print(time_tuple)# 1970-01-01-08-01-00# 有中文在windows下报错
tst = (1970, 1, 1, 8, 0, 0, 0, 0, 0)
time_tuple = time.strftime(%Y-%m哈哈-%d-%H-%m-%S,tst)
print(time_tuple)# 1970-01-01-08-01-00
strptime -- 格式化时间格式化时间,通过格式化字符串将一个字符串中的时间变成时间元组。
import time# 格式化字符串要和原字符串一模一样,只是将需要提出的部分使用占位符替换
char = 2000年10月30日一个伟大的中国少年在三晋大地诞生了
format_char = %Y年%m月%d日一个伟大的中国少年在三晋大地诞生了tst = time.strptime(char, format_char)
print(tst)
sleep -- 时间睡眠等待指定秒数的时间:
import timeprint(开始睡觉)
time.sleep(2)
print(睡了两秒钟,神清气爽)
perf_counter -- 时间计时用于计算程序运行的时间
import time# perf_counter 用于计算程序运行的时间# 记录开始时间
start_time = time.perf_counter()# 程序运行
for i in range(10000):
pass# 记录时间
end_time = time.perf_counter()# windows系统直接拿到第二次的值就可以了,不用减去第一次的值也行
print(end_time, 秒)# 0.0003918 秒
print(end_time - start_time, 秒)# 0.0003916 秒
如果使用多次
perf_counter()
函数,直接输出其的值是距第一次使用的时间长度:import timetime1 = time.perf_counter()
time.sleep(1)
time2 = time.perf_counter()
print(time2)time.sleep(2)
time3 = time.perf_counter()
print(time3)time.sleep(3)
time4 = time.perf_counter()
print(time4)"""
结果:
1.0002558
3.0048941
6.019172
"""
注意:windows系统下使用
perf_counter()
函数可以直接输出耗时长度,每次的耗时默认都是距离第一次使用perf_counter()
函数的时间长度;如果在linux系统下使用perf_counter()
函数则必须要使用第二次的结果减去之前的结果,因为在linux系统中perf_counter()
函数的值和time()
函数的值都是一样的,那就是返回一个时间戳。使用
time.time()
计算时间import time# perf_counter 用于计算程序运行的时间# 记录开始时间
start_time = time.time()# 程序运行
for i in range(10000):
pass# 记录时间
end_time = time.time()print(end_time - start_time, 秒)# 0.001001119613647461 秒
耗时短的计时推荐使用
pref_counter
,耗时长的推荐使用time
。模拟进度条
# 1、定义进度条样式
print([%-50s] % (###########))
print([%-50s] % (###################))
print([%-50s] % (###########################))
print([%-50s] % (####################################))
print([%-50s] % (########################################))
# 2、让进度条动起来
import timeprogress_char =
for i in range(50):
progress_char += #
time.sleep(0.05)# 延时看起来不是很快
# end使不能换行,\\r使进度条不断刷新,保持在同一行显示;
print(\\r[%-50s] % (progress_char), end=)
print(\\n)
# 3、根据文件的大小调整进度条的进度
import timedef progress(percent):
"""控制进度条的显示
参数是下载的百分比,用来控制进度条的进展
"""
# 如果百分比超过了1,说明数据已经接受完毕
if percent >
1:
percent = 1# 打印对应的进度条效果
char = # * int(percent * 50)
print(\\r[%-50s]%d%% % (char, int(percent * 100)), end=)# 已下的大小
rec_size = 0# 下载文件的大小
total_size = 102400# 模拟下载过程
while rec_size <
total_size:
rec_size += 10240# 下载速度
time.sleep(0.05)# 模拟网络延迟
percent = rec_size / total_size# 计算下载的进度(百分比)
# 调用进度条
progress(percent)
程序计时在学习了
perf_counter
计时后,我们知道有很多种方法可以用于计时:- time函数:返回当前时间戳,使用time函数计时是获取两个节点各自的时间戳,然后计算其之间的差值,即为耗时时长。
- 优点:计算的是真实世界中的时间长度,而且计时本身不消耗计算机资源,计算长时间的程序优势较大;
- 缺点:time函数的时间获取来源于计算机本身的时间,如果在计时途中计算机的时间发生变化,比如人为的调快一小时,那么计时就会比正确的时间慢一个小时的时间。
- perf_counter函数:是time模块中专门用于性能计时的函数,具有高分辨率的时钟,已测量短持续的时间。
- 优点:是专门用于性能计时的函数,精确度高,适合计算耗时短的程序;
- 缺点:专门用于计时的函数,计时本身就会消耗计算机资源,所以计时过长难免会有一定的影响;
- process_time函数:用于评测处理时间,计算内核和用户空间CPU时间之和,这个时间不包含程序阻塞的时间,比如time.sleep()、input()等。
- 优点:专门用于计算程序本身内在的时间消耗,排除外来因素、提升系统本身效率、优化程序使用;
import timedef loop():
time.sleep(1)
input(请输入:)# 这个位置人为数三秒回车执行
num = 10 ** 8
for _ in range(num):
pass
time.sleep(1)# time.time
start_time = time.time()
loop()
end_time = time.time()
print(start_time)# 1640270620.4077902
print(end_time)# 1640270628.1165576
print(end_time - start_time)# 7.708767414093018# time.perf_counter
start_time = time.perf_counter()
loop()
end_time = time.perf_counter()
print(start_time)# 3e-07
print(end_time)# 7.823952
print(end_time - start_time)# 7.8239517# time.process_time
start_time = time.process_time()
loop()
end_time = time.process_time()
print(start_time)# 3.234375
print(end_time)# 4.8125
print(end_time - start_time)# 1.578125
除此之外,python3.7之后,新增了精确到纳秒的函数:
- time.time_ns()
- time.perf_counter_ns()
- time.process_time_ns()
timeit
用于程序的性能计时。时间转换示意图在上述的几种类型中存在时间转换的问题,详情和之间的关系可以参考下图:
文章图片
datetime时间模块
import datatime
datatime
模块重新封装了time模块,提供更多的接口。date类
date
类专门用于描述日期,实例化对象时必须填入参数,分别表示:年、月、日,返回datetime.date
对象。from datetime import datedate_o = date(2022, 3, 1)print(date_o)
print(type(date_o))"""
结果:
2022-03-01
<
class datetime.date>
"""
常用属性
属性 | 作用 |
---|---|
year | date对象表示的具体年份(实例化对象调用达到效果); |
month | date对象表示的具体月份(实例化对象调用达到效果); |
day | date对象表示的具体日(实例化对象调用达到效果); |
max | date类能够表示的最大日期; |
min | date类能够表示的最小日期; |
resolution | date类能够表示的最小单位; |
方法 | 作用 |
---|---|
today() | 返回本地日期对象; |
fromtimestamp(time_stamp) | 给定时间戳返回日期对象; |
replace(y, m, d) | 给定年月日返回日期对象; |
timetuple() | 返回本地当前时间元组time.struct_time 对象;
|
weekday() | 返回星期序号,星期一返回0; |
isoweekday() | 返回星期序号,星期一返回1; |
isocalendar() | 返回元组,表示日期的年份、第几周、第几周之后的第几天; |
isoformat() | 返回时间字符串; |
strftime() | 格式化日期,参考time.strftime() ; |
time
类是datetime
模块中专门用于描述时间的类,四个参数:hour
、minute
、second
、microsecond
默认都为0。from datetime import timetime_0 = time()print(time_0)
print(type(time_0))"""
结果:
00:00:00
<
class datetime.time>
"""
time
的属性和date
类的属性方法基本相同,可以参考使用;datetime类
相同于
date
和time
两个类的结合,使用基本相同;timedelta类
timedelta
类用于时间运算,类的参数有datetime
模块支持的所有时间单位,使用其它的时间和日期对象可以和timedelta
对象进行时间加减运算,注意在实例化时使用关键字传参;from datetime import datetime
from datetime import timedelta# 日期对象
datetime_o = datetime(2000, 10, 30, 14, 40, 6)
print(datetime_o)# ## 假设我们要计算这个时间5天4小时23分6秒之后的时间# 实例化 5天4小时23分6秒 的timedelta对象
timedelta_o = timedelta(days=5, hours=4, minutes=23, seconds=6)# 将时间对象和timedelta对象相加
datetime_o += timedelta_o
print(datetime_o)"""
结果:
2000-10-30 14:40:06
2000-11-04 19:03:12
"""
推荐阅读
- #yyds干货盘点# js学习笔记四十复杂工厂模式
- 译Golang 的艺术哲学和科学 #导入Word文档图片#
- k8scfssl证书工具使用手册,如何详细的学习cfssl的使用()
- It‘s likely that neither a Result Type nor a Result Map was specified
- ps扣玻璃杯
- 世上根本没有什么感同身受,只有冷暖自知
- tree树状图表格的呈现,数据结构
- HB打包的apk进行升级
- 合并table