Python自动化运维之时间模块
时间模块
世界协调时(UTC),也被称为格林尼治天文(或格林威治)时间、世界标准时间或GMT时间,是全球时间的统一标准。与之相对的是各个时区的本地时间。在东N区,本地时间比UTC时间早N个小时,因此可以通过UTC时间加上N小时来得出;而在西N区,本地时间则比UTC时间晚N个小时,即通过UTC时间减去N小时来计算。中国位于东8区,因此其本地时间比UTC时间早8小时,通常以UTC+8来表示。

时间戳,也被称为Unix时间或POSIX时间,是一种特定的时间表示方法。它记录了从格林尼治时间1970年1月1日0时0分0秒起,至今所经过的毫秒数。这种时间戳的数值类型为float。但请注意,不同编程语言中相关方法返回的时间单位可能有所不同,例如Python中可能返回的是秒数。因此,在使用时需仔细查阅方法的文档说明。此外,时间戳表示的是一种时间差值,其值与时区设置无关。
对时间的使用相对固定,主要为以下场景:
- 计算程序的运行时间(endtime6-begintime1);
- 时间类型转换;系统生成的log中的时间字符串,变化成需要的格式化字符串格式;
- 时间的运算;
2.1. time
使用time模块的语法参考标签
'''
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(0000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12),下午测试:13-->1点
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
'''
import time
#输出时间戳,2025/11/17 10:59:00 距离:1970/1/1 0:0:0的绝对时间
print(time.time())
#实际上时间元组是:(2020,9,23,17,37,22,2,267,0)
# 时间元组(年、月、日、时、分、秒、一周的第几日、一年的第几日、夏令时)
# 一周的第几日: 0-6
# 一年的第几日: 1-366
# 夏令时: -1, 0, 1
t1 = time.localtime()
print(t1)
#time.struct_time(tm_year=2023, tm_mon=10, tm_mday=27, tm_hour=11, tm_min=58, tm_sec=21, tm_wday=4, tm_yday=300, tm_isdst=0)
#可以通过这个对象获取里面对应的属性
print(t1.tm_year)
#今天是星期几,一般要 +1
print(t1.tm_wday)
#今天是今年的第几天
print(t1.tm_yday)
#通过下标获取元素的值,等同于t1.tm_year,t1的第一个key
print(t1[0])
#可视化时间
time.ctime() # 输出:Wed Sep 23 17:41:32 2020
t2 = time.time() # 获取当前时间距离 1970 1 1 的秒值
print(t2)
print(int(t2)) # 强转时间戳
#时间格式化:日期格式转换成字符串
print(time.strftime("%Y-%m-%d %H:%M:%S",t1))
print(time.strftime("%Y-%m-%d %p %H:%M:%S 今天是星期%w 是今年的第%j天",t1))
#解析:将一个字符号串变为一个时间对象,所以后面的格式必须严格按照前面的数据格式定义
#前面是固定格式,后面的参数要和前面的保持一致
t3 = time.strptime("2023-10-27 12:09:12","%Y-%m-%d %H:%M:%S")
#输出下面内容
print(t3)
time.struct_time(tm_year=2023, tm_mon=10, tm_mday=27, tm_hour=12, tm_min=9, tm_sec=12, tm_wday=4, tm_yday=300, tm_isdst=-1)
#只要知道年月日,计算今天周几,今天是今年的第几天,很快就可以获得
t3 = time.strptime("2022-11-08","%Y-%m-%d")
#第几天,对不对?yday:一年中的第几天
print(t3.tm_yday)
#wday一周的第几天,从0开始,所以11-15号是5,对应的就是周六
print(t3.tm_wday)
#将一个时间元组对象转换为对应的秒
timestamp = time.mktime(t3)
print(timestamp)
#将指定的秒值变为一个时间元组对象
t4 = time.localtime(1667836800)
print(t4)
#sleep(n):休眠函数将线程休眠 几秒中
time.sleep(5)
2.2. datetime
datetime 模块与 time 模块的区别
- time 的时间范围:1970年 - 2038年,1970.1.1 00:00:00以秒计算的偏移量
datatime 的时间范围:0年 - 9999年 - datetime 是 time 的高级封装,所以比time模块的功能强大一些;
- 在对时间要求不多的项目里,两个模块都可以满足需求;
import datetime
date = datetime.date(2022, 10, 10)
print(date)
print(type(date))
#带年月日时分秒的写法
date2 = datetime.datetime(2022, 10, 10, 12, 13, 15)
print(date2)
print(type(date2))
#只有时分秒的写法
date3 = datetime.time(17, 59, 59)
print(date3)
#通过datetime获取当前时间
d3 = datetime.datetime.now()
print(d3)
print(type(d3)) # <class 'datetime.datetime'>
print(d3.date())
print(d3.year)
print(d3.month)
print(d3.weekday()) # 比真实的星期小1
#时间的格式化与反格式化
print(d3.strftime('%Y/%m/%d %p %I:%M:%S'))
s1 = "2023/10/27 PM 02:30:15"
#解析 就是将一个字符串转换为对象的过程,最后得到的是对象
d4 = d3.strptime(s1, "%Y/%m/%d %p %I:%M:%S")
#打印的是一个对象,其实打印的是这个对象的
print(d4) # 2023-10-27 14:30:15
#通过这个对象如何获取时间戳呢
print(d4.timestamp()) # 1698388215.0
#假如我有一个时间戳,如何变为对象呢?
d5 = datetime.datetime.fromtimestamp(1989388215)
print(d5.year) # 2033
d1 = datetime.datetime(2022, 7, 31)
d2 = datetime.datetime(2022, 5, 16, 17, 56, 24)
diff = d1 - d2 # 相减以后是一个对象
#可以计算两个时间的差值
print(diff)
print(diff.days)
#相差的天数不算,只计算除了天数以外的时分秒的秒值
print(diff.seconds)
#两个时间相差的秒值
print(diff.total_seconds())
#要计算差多少月 多少年,这里没有;
now = datetime.datetime.now()
print(now)
#三天后的时间
print(now + datetime.timedelta(days=3))
#一星期前的时间
print(now - datetime.timedelta(weeks=1))
timedelta 是 Python datetime 模块中的一个 时间差对象,核心作用是「表示两个日期 / 时间之间的间隔」—— 比如 “2 天 5 小时 30 分钟”“76 天 8 小时 3 分 36 秒”,本质是对「时间差」的结构化封装(不是单个数字,而是包含天、秒、微秒等维度的对象)。
2.3 运维案例
场景:
模拟文件下载 / 数据传输的过程,在终端实时显示进度(用 # 填充进度条,配合百分比),让用户直观看到任务执行进度。
核心代码
def progress(percent, width=50):
if percent > 1:
percent = 1
completed_count = int(width * percent)
# f-string直接填充#和空格,{:<%d}表示左对齐,总长度width
show_str = f'[{"#"*completed_count:<{width}}]' # 关键:<{width} 左对齐,剩余补空格
print(f'\r{show_str} {int(100*percent)}%', end='')
progress(0.3,5)
进一步升级代码
import time # 导入时间模块,用于模拟传输延迟time.sleep(0.1)
# 初始化变量:
recv_size = 0 # 已接收的数据量(初始为 0)
total_size = 100000 # 总数据量(模拟要传输的文件/数据大小)
# 循环:只要已接收数据 < 总数据量,就继续传输
while recv_size < total_size:
time.sleep(0.1) # 模拟传输延迟(每接收一次,暂停 0.1 秒,让进度条肉眼可见)
recv_size += 100 # 每次接收 100 单位数据(可理解为“分片传输”)100 200 300
#100/100000=0.001
# 计算当前进度百分比(已接收 / 总大小)
percent = recv_size / total_size
# 调用进度条函数,更新显示
progress(percent)
两个特殊字符和 end 参数:\r(回车符) 负责 “覆盖当前行”,\n(换行符) 负责 “新建一行”,而 end='' 控制 print 函数默认的换行行为。我们分两组代码对比分析:
注意:
在 Python 的 print 中:
- 默认行为:
print(xxx)等价于print(xxx, end='\n')—— 打印内容后自动加\n(换行符),新建一行; \r(回车符):不会新建一行,只会把光标移到「当前行的开头」,后续打印的内容会直接覆盖当前行的原有内容(这是实现 “进度条覆盖更新” 的核心);\n(换行符):直接新建一行,光标移到下一行开头,必然触发换行。
- 点赞
- 收藏
- 关注作者
评论(0)