您现在的位置是:网站首页> 编程资料编程资料

详解Python常用标准库之时间模块time和datetime_python_

2023-05-26 354人已围观

简介 详解Python常用标准库之时间模块time和datetime_python_

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

小知识:最开始的时候,时间戳的开始年份是1971年,那个时候Unix系统和C语言刚刚诞生,所以时间戳0也就是Unix系统和C语言的生日。那时候的时间位数只有32位,而且每秒中有60个数字,发现只要两年多的时间时间戳就能完成一个轮回,十分的不方便!所以后来的一系列改革,将时间戳的数值改为每秒1个数字,还有一些新的系统可以将时间戳的位数增大,可以让时间戳的轮回扩展到一百多年,再后来为了方便人们记忆,将时间戳的起始年份定位1970年整。

import time stamp_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) 

有大问题啦!!!

时间戳的起始时间是1970-1-1 0:0:0, 这个时候的时间戳是0,那么时间戳3600就是整整一个小时之后,那么时间就应该是1970-1-1 0:1:0 才对的呀!怎么上面的3600确实9点钟了呢?怎么起始时间变成了8点了呢?

然后你发现你在中国,时间是北京时间,北京在东八区时区,嘶,怎么正好也是个八?

是这样的,按照道理来说的话全世界任何一个地方的时间戳所代表的时间都应该是一样的,而且时间戳的起始时间确实是 1970-1-1 0:0:0 ,但是这个时间是位于英国的一个叫做格林威治的小镇的,格林威治有一个天文台叫做皇家格林尼治天文台,后来国际上将这个地方的经线作为本初子午线,作为时间计算时间和地理精度的起点。那么,有时区的存在打破了这个可能,我们在中国,所有的设备都是按照中国的时区编码的,中国位于东八区,在时间上比英国快八个小时,所以我们中国的本地时间戳就是 1970-1-1 8:00:00。

gmtime -- 获取时间元组(GMT)

在不知道这个函数的时候,我就很好奇为什么localtime的初始时间比格林威治时间要快8小时,现在就明白了:

函数描述
gmtime获取时间元组(GMT格林威治时间)
localtime获取时间元组(UTC协调世界时)

mktime -- 时间元组获取时间戳

注意:

  • 参数必须是时间元组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 Nov 1 21:34:39 2021 # 星期 月 日 时 分 秒 年 # 默认为本地时间戳 time_char = time.ctime() print(time_char) # Mon Nov 1 21:34:39 2021 # 指定时间戳 time_char = time.ctime(0) print(time_char) # Thu Jan 1 08:00:00 1970 

asctime -- 时间元组获取时间字符串

注意,asctime有弊端,看下例:

import time tst = (1970, 1, 1, 8, 24, 61, 1, 0, 0) time_char = time.asctime(tst) print(time_char) # Tue Jan 1 08:24:61 1970 tst = (1970, 1, 1, 8, 24, 61, 2, 0, 0) time_char = time.asctime(tst) print(time_char) # Tue Jan 1 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 time print('开始睡觉') 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 time time1 = 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 time progress_char = '' for i in range(50): progress_char += '#' time.sleep(0.05) # 延时看起来不是很快 # end使不能换行,\r使进度条不断刷新,保持在同一行显示; print('\r[%-50s]' % (progress_char), end='') print('\n') 
# 3、根据文件的大小调整进度条的进度 import time def 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模块中专门用于性能计时的函数,具有高分辨率的时钟,已测量短持续的时间。

  • 优点:是专门用于性能计时的函数,精确度高,适合

-六神源码网