时间模块
time 模块
时间表示方式
- **时间戳 timestamp:**表示的是从 1970 年1月1日 00:00:00 开始按秒计算的偏移量
- **UTC(Coordinated Universal Time, 世界协调时)**亦即格林威治天文时间,世界标准时间。在中国为 UTC+8 DST(Daylight Saving Time) 即夏令时;
- 结构化时间(struct_time): 由 9 个元素组成
结构化时间(struct_time)
使用 time.localtime()
等方法可以获得一个结构化时间
>>> import time
>>> time.localtime()
time.struct_time(tm_year=2021, tm_mon=9, tm_mday=1, tm_hour=14, tm_min=23, tm_sec=29, tm_wday=2, tm_yday=244, tm_isdst=0)
结构化时间共有9个元素,按顺序排列如下表:
索引 | 属性 | 取值范围 |
---|---|---|
0 | tm_year(年) | 比如 2021 |
1 | tm_mon(月) | 1 - 12 |
2 | tm_mday(日) | 1 - 31 |
3 | tm_hour(时) | 0 - 23 |
4 | tm_min(分) | 0 - 59 |
5 | tm_sec(秒) | 0 - 59 |
6 | tm_wday(weekday) | 0 - 6(0表示周一,6表示周日) |
7 | tm_yday(一年中的第几天) | 1 - 366 |
8 | tm_isdst(是否是夏令时) | 默认为-1 |
然结构化时间是一个序列,那么就可以通过索引进行取值,也可以进行分片,或者通过属性名获取对应的值。
>>> import time
>>> t = time.localtime()
>>> t
time.struct_time(tm_year=2021, tm_mon=9, tm_mday=1, tm_hour=14, tm_min=23, tm_sec=29, tm_wday=2, tm_yday=244, tm_isdst=0)
>>> t[3]
14
>>> t[1:3]
(9, 1)
>>> t.tm_mon
9
注意
但是要记住,Python的time类型是不可变类型,所有的时间值都只读,不能改
>>> t.tm_mon = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: readonly attribute
格式化时间字符串
利用 time.strftime('%Y-%m-%d %H:%M:%S')
等方法可以获得一个格式化时间字符串
>>> import time
>>> time.strftime('%Y-%m-%d %H:%M:%S')
'2021-09-01 02:39:23'
注意其中的空格、短横线和冒号都是美观修饰符号,真正起控制作用的是百分符
对于格式化控制字符串 "%Y-%m-%d %H:%M:%S
,其中每一个字母所代表的意思如下表所示,注意大小写的区别:
格式 | 含义 | 格式 | 含义 |
---|---|---|---|
%a | 本地简化星期名称 | %m | 月份(01 - 12) |
%A | 本地完整星期名称 | %M | 分钟数(00 - 59) |
%b | 本地简化月份名称 | %p | 本地am或者pm的相应符 |
%B | 本地完整月份名称 | %S | 秒(01 - 59) |
%c | 本地相应的日期和时间 | %U | 一年中的星期数(00 – 53,星期日是一个星期的开始) |
%d | 一个月中的第几天(01 - 31) | %w | 一个星期中的第几天(0 - 6,0是星期天) |
%H | 一天中的第几个小时(24小时制,00 - 23) | %x | 本地相应日期 |
%I | 第几个小时(12小时制,01 - 12) | %X | 本地相应时间 |
%j | 一年中的第几天(001 - 366) | %y | 去掉世纪的年份(00 - 99) |
%Z | 时区的名字 | %Y | 完整的年份 |
time 模块主要方法
1. time.sleep(t)
time 模块最常用的方法之一,用来睡眠或者暂停程序t秒,t可以是浮点数或整数。
import time
# 1. time.sleep(t): 用来睡眠或者暂停程序t秒
def banzhuan():
print("start...")
time.sleep(3) # 3s
print("end...")
banzhuan() # 调用函数
2. time.time()
返回当前系统时间戳。时间戳可以做算术运算。
import time
# 1. time.sleep(t): 用来睡眠或者暂停程序t秒
def banzhuan():
print("start...")
time.sleep(3) # 3s
print("end...")
# 2. time.time(): 返回当前系统时间戳,可以做算术运算
# print(time.time()) # 1656314125.2967942
start_time = time.time() # 记录开始的时间
banzhuan() # 调用函数
end_time = time.time() # 记录结束的时间
print("耗时:", end_time-start_time)
3. time.gmtime([secs])
将一个时间戳转换为 UTC时区的结构化时间。可选参数secs的默认值为 time.time()
。
import time
t1 = time.gmtime() # time.gmtime(time.time())
print(t1)
print(t1[0], t1[1], t1[2]) # 年份 月份 日
print(t1[:3]) # (年份 月份 日)
print(t1.tm_hour, t1.tm_min, t1.tm_sec) # 时 分 秒
4. time.localtime([secs])
将一个时间戳转换为 当前时区 的结构化时间。如果secs参数未提供,则以当前时间为准,即time.time()
。
import time
t2 = time.localtime(time.time()+60*60)
print(t2)
print(t2[0], t2[1], t2[2]) # 年份 月份 日
print(t2[:3]) # (年份 月份 日)
print(t2.tm_hour, t2.tm_min, t2.tm_sec) # 时 分 秒
5. time.mktime(t)
结构化时间转换为时间戳,t(结构化时间)
import time
t3 = time.mktime(time.localtime())
print(t3) # 1656316578.0
6. time.strftime(format [, t])
返回格式化字符串表示的当地时间。把一个struct_time
(如time.localtime()
和time.gmtime()
的返回值)转化为格式化的时间字符串,显示的格式由参数format
决定。如果未指定t,默认传入time.localtime()
。
import time
# %Y:年 %m:月 %d:日 %H:小时 %M:分钟 %S:秒
t4 = time.strftime("%Y-%m-%d %H:%M:%S")
print("t4:", t4) # 2022-06-27 16:20:27
7. time.strptime(string[,format])
将格式化时间字符串转化成结构化时间
- 该方法是
time.strftime()
方法的逆操作。 time.strptime()
方法根据指定的格式把一个时间字符串解析为结构化时间。- 提供的字符串要和 format参数 的格式一一对应
- 如果string中日期间使用 “-” 分隔,format中也必须使用“-”分隔
- 时间中使用冒号 “:” 分隔,后面也必须使用冒号分隔
- 并且值也要在合法的区间范围内
import time
t5 = time.strptime("2099-06-09 13:13:13","%Y-%m-%d %H:%M:%S")
print(t5)
t6 = time.strptime("2011-12-12", "%Y-%m-%d")
print(t6)
print(t5 > t6) # True 结构化时间越靠后的越大
时间格式之间的转换
Python的三种类型时间格式,可以互相进行转换
从 | 到 | 方法 |
---|---|---|
时间戳 | UTC结构化时间 | gmtime() |
时间戳 | 本地结构化时间 | localtime() |
本地结构化时间 | 时间戳 | mktime() |
结构化时间 | 格式化字符串 | strftime() |
格式化字符串 | 结构化时间 | strptime() |
练习:取出指定时间段的日志
需求
-
有一日志文件,按时间先后顺序记录日志
-
给定 时间范围,取出该范围内的日志
-
自定义日志文件 myweb.log
[root@localhost ~]# vim /opt/myweb.log 2030-01-02 08:01:43 aaaaaaaaaaaaaaaaa 2030-01-02 08:34:23 bbbbbbbbbbbbbbbbbbbb 2030-01-02 09:23:12 ccccccccccccccccccccc 2030-01-02 10:56:13 ddddddddddddddddddddddddddd 2030-01-02 11:38:19 eeeeeeeeeeeeeeee 2030-01-02 12:02:28 ffffffffffffffff
【方案一】
# 取出指定时间段 [9点~12点] 的行
import time
# strptime(), 将字符时间'2030-01-02 09:00:00',转换成时间对象
t9 = time.strptime('2030-01-02 09:00:00', '%Y-%m-%d %H:%M:%S')
t12 = time.strptime('2030-01-02 12:00:00', '%Y-%m-%d %H:%M:%S')
# 读取日志文件myweb.log中的数据
with open('myweb.log', mode="r") as fobj:
for line in fobj.readlines():
# strptime(), 将line[:19]截取的字符时间,转换成时间对象
t = time.strptime(line[:19], '%Y-%m-%d %H:%M:%S')
if t9 <= t <= t12: # 此种判断会遍历日志文件中的每一行,有可能执行大量无效操作,效率低下
print(line, end='')
【方案二】
# 日志文件中,时间点是从前往后不断增加的,所以只要遍历到有一行时间超过预计,则后面的所有行均是不满足条件的
import time
# strptime(), 将字符时间'2030-01-02 09:00:00',转换成时间对象
t9 = time.strptime('2030-01-02 09:00:00', '%Y-%m-%d %H:%M:%S')
t12 = time.strptime('2030-01-02 12:00:00', '%Y-%m-%d %H:%M:%S')
with open('myweb.log', mode="r") as fobj: # 读取日志文件myweb.log中的数据,逐行进行遍历
for line in fobj.readlines():
# strptime(), 将line[:19]截取的字符时间,转换成时间对象
t = time.strptime(line[:19], '%Y-%m-%d %H:%M:%S')
if t > t12: # 当时间大于12点时,退出循环
break
if t >= t9: # 当时间大于9点时,打印对应行
print(line, end='')