引言
本篇主要想总结一些关于时间处理上的问题,以及我认为比较多star包的学习笔记。
时间戳与时间格式的互转
这个是最基本的一个功能,很多时候从数据库或者其它地方查询到的数据需要在代码上变为时间戳判断或者定时,所以两种转换分别为:
时间戳转时间:
import time
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
print(timeArray,type(timeArray))
formatTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
print(formatTime)
时间转换为时间戳:
# 字符类型的时间
tss1 = '2021-02-12 15:52:02'
# 转为时间数组
timeArray = time.strptime(tss1, "%Y-%m-%d %H:%M:%S")
print(timeArray)
# timeArray可以调用tm_year等
print(timeArray.tm_year) # 2021
# 转为时间戳
timeStamp = int(time.mktime(timeArray))
print(timeStamp) # 1613116322
关于datetime数据格式的函数,大致用的是以下四种:
用法 | 解释 |
---|---|
datetime.today() | 当前时间,localtime |
datetime.now([]) | 当前时间默认 localtime |
datetime.utcnow() | UTC 时间 |
datetime.fromtimestamp(timestamp[, tz]) | 由 Unix Timestamp 构建对象 |
datetime.strptime(date_string, format) | 给定时间格式解析字符串 |
其余的一些date使用方式可以参考 获取系统时间 文中的下图:
根据上表的时间变换图,我们就能知道大概的一个数据流走向,然后这里还需要提一下关于st_atime,st_mtime还有st_ctime的区别,如果说我们要对文件或者文件夹做监控,那么一般只需要拿到st_ctime对其进行判断就可以,其它时间在我的测试结果里发现没有变化,获取文件夹与文件更改时间是通过os.walk与os.stat,walk是在做递归,而stat函数比较有意思,它的接收值与返回值分别为:
参数:
- path – 指定路径
返回值:
stat的结构体:
- st_mode: inode 保护模式
- st_ino: inode 节点号。
- st_dev: inode 驻留的设备。
- st_nlink: inode 的链接数。
- st_uid: 所有者的用户ID。
- st_gid: 所有者的组ID。
- st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
- st_atime: 上次访问的时间。
- st_mtime: 最后一次修改的时间。
- st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
上面的四个时间,从我测试来看,st_ctime还是会比较准的,我的实验场景是在一个文件夹里不断将图片合成视频。
python时间模块比较
这里我们只比较两个git上star比较多的模块,arrow和dateutil,前者还需要pip安装,而后者好像在conda集成环境里已经是作为内置包,我不太清楚python直接安装是否也有,那么首先来介绍arrow:
arrow说明
arrow作为6.7k的star在火热程度上已经是榜首了,它的很多操作的简单化,以及各种时间处理上给人的感觉都要无比顺畅,依旧是上面的问题,时间戳与时间的互转,代码为:
当前时间转为时间戳:
nowTime = arrow.now()
print(nowTime) # 2021-02-12T17:17:39.125537+08:00
localTimeStamp = nowTime.timestamp
print(localTimeStamp) # 1613121628
时间戳转为当时时间:
localTime = arrow.get(localTimeStamp)
print(localTime.format())
我们可以发现这要远远简单于上面的datetime结构,甚至还有一些其它的例子都简单于它:
获取当前时间 arrow.utcnow(), arrow.now()
>>> arrow.utcnow()
2021-02-12T09:29:12.168381+00:00
>>> arrow.now()
2021-02-12T17:29:34.668527+08:00
将时间戳转化为arrow对象 arrow.get(timestamp)
好像目前版本的timestamp参数必须为int类型,我看其余很多教程能丢字符串,但我尝试下发现不行:
print(arrow.get(1613121628)) # 2021-02-12T09:20:28+00:00
# print(arrow.get('1613121628'))
print(arrow.get(1613121628.16652)) # 2021-02-12T09:20:28.166520+00:00
print(arrow.get("1613121628.16652")) # arrow.parser.ParserError: Could not match input '1613121628.16652' to any of the following formats: YYYY-MM-DD, YYYY-M-DD, YYYY-M-D, YYYY/MM/DD, YYYY/M/DD, YYYY/M/D, YYYY.MM.DD, YYYY.M.DD, YYYY.M.D, YYYYMMDD, YYYY-DDDD, YYYYDDDD, YYYY-MM, YYYY/MM, YYYY.MM, YYYY, W
将字符串转换为arrow对象 arrow.get(string[,format_string])
>>> arrow.get('2021-02-12 17:30:45', 'YYYY-MM-DD HH:mm:ss')
2021-02-12T17:30:45+00:00
还有很多其余操作我就直接写成一个代码块了:
# 从字符串中通过格式参数搜索时间
>>> arrow.get('June was born in May 1980', 'MMMM YYYY')
1980-05-01T00:00:00+00:00
# arrow对象属性 datetime,timestamp,native,tzinfo
>>> a = arrow.utcnow()
>>> a.datetime
datetime.datetime(2021, 2, 12, 9, 39, 13, 254194, tzinfo=tzutc())
>>> a.timestamp
1613122753
>>> a.naive
datetime.datetime(2021, 2, 12, 9, 39, 13, 254194)
>>> a.tzinfo
tzutc()
# 时间推移 a.shift(**kwargs)
>>> a.shift(weeks=+3) #三周后
<Arrow [2021-03-05T09:39:13.254194+00:00]>
>>> a.shift(days=-1) #一天前
<Arrow [2021-02-11T09:39:13.254194+00:00]>
>>> a.shift(weekday=6) #距离最近a的星期日,weekday从0到6
<Arrow [2021-02-14T09:39:13.254194+00:00]>
但是虽然arrow相比于datetime的方法类型更加多样化,但是从性能层面考虑,是比较慢的,下面的图是我搜到一篇博文,它对比于当时几种时间格式的各种操作,做了benchmark:
此图来自于https://pendulum.eustace.io/faq/,这只是我截取的一张,如果想要看全部的测试结果请进网站查看。