python常用标准库(时间模块time和datetime)

【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协调世界时)
mktime -- 时间元组获取时间戳注意:
  1. 参数必须是时间元组time.struct_time 或者元组 tuple 类型;
  2. 元组中的元素一个也不能少,必须九个元素都存在;
  3. 得到的时间戳只收到前六个值的影响,即:年月日时分秒;
  4. 时间元组中的时间表示,最小时间不能低于当地的最小时间戳;
  5. 时间元组中的时间表示,单位可以超出原本的范围,比如秒满60进1,我们将秒写成100,系统也不会报错,但是时间上会自动的将多出的时间进位。但是数字也不能过大,因为数据类型的大小是有极限的。
  6. 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计时后,我们知道有很多种方法可以用于计时:
  1. time函数:返回当前时间戳,使用time函数计时是获取两个节点各自的时间戳,然后计算其之间的差值,即为耗时时长。
    • 优点:计算的是真实世界中的时间长度,而且计时本身不消耗计算机资源,计算长时间的程序优势较大;
    • 缺点:time函数的时间获取来源于计算机本身的时间,如果在计时途中计算机的时间发生变化,比如人为的调快一小时,那么计时就会比正确的时间慢一个小时的时间。
  2. perf_counter函数:是time模块中专门用于性能计时的函数,具有高分辨率的时钟,已测量短持续的时间。
    • 优点:是专门用于性能计时的函数,精确度高,适合计算耗时短的程序;
    • 缺点:专门用于计时的函数,计时本身就会消耗计算机资源,所以计时过长难免会有一定的影响;
  3. 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之后,新增了精确到纳秒的函数:
  1. time.time_ns()
  2. time.perf_counter_ns()
  3. time.process_time_ns()
还有标准库timeit用于程序的性能计时。
时间转换示意图在上述的几种类型中存在时间转换的问题,详情和之间的关系可以参考下图:
python常用标准库(时间模块time和datetime)

文章图片

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类
time类是datetime模块中专门用于描述时间的类,四个参数:hourminutesecondmicrosecond默认都为0。
from datetime import timetime_0 = time()print(time_0) print(type(time_0))""" 结果: 00:00:00 < class datetime.time> """

time的属性和date类的属性方法基本相同,可以参考使用;
datetime类
相同于datetime两个类的结合,使用基本相同;
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 """


    推荐阅读