Python 利用 Arrow 库转换时间格式

最近发现个 Python 时间库 arrow,相比 time、datetime 等标准库,arrow 提供了更合理和人性化的方法来创建、操作、格式化和转换日期、时间和时间戳。

话说之前有个需求:把一组非标准格式的日期加时间字符串,如 2020年12月20日 22点7分5秒,转换为 YYYY-MM-DD HH:mm:ss2020-12-20 22:07:05 这样的标准格式。

通常会想到用 time 或 datetime 库来格式化,比如:

# 用 time 模块
import time

# 先转为 struct_time 
a = time.strptime("2020年12月20日 22点7分5秒", "%Y年%m月%d日 %H点%M分%S秒")
fmt = "%Y年%m月%d日 %H点%M分%S秒"
# 转为所需格式,输出 '2020-12-20 22:07:05'
time.strftime(fmt, a)


# 或者用 datetime 模块,看似简洁一点
from datetime import datetime

fmt = "%Y年%m月%d日 %H点%M分%S秒"
# 同样输出 '2020-12-20 22:07:05'
str(datetime.strptime("2020年12月20日 22点7分5秒", fmt))

问题解决了,可事情往往没这么简单:又来了几批数据,时间格式是这样的:2020/12/20 22:0712/22 2020 22:07:05二零二零年十二月二十二日 等等,总之它们的样子各不相同,可能没有秒钟精度,或者年月日顺序不同。

当然,可根据来源添加 if...else,分别设置不同的 fmt 后转换,但这肯定不是 Pythonic:不优雅。

现在祭出 arrow,这里用到它的一个特性:可使用正则表达式来格式化日期,避免碰到包含各种不规则符号分割的日期时间字符串,而且,fmt 还可以是一个正则表达式的列表,代码:

import arrow

# 列表里是可能碰到的各种日期时间格式
fmt = [
    r'YYYY[\S*]MM[\S*]DD[\S*] HH[\S*]mm[\S*]ss[\S*]',
    r'MM[\S*]DD[\S*] YYYY HH[\S*]mm[\S*]ss[\S*]',
    r'YYYY[\S*]MM[\S*]DD[\S*] HH[\S*]m[\S*]s[\S*]',
]

my_date = [
    '2020年12月20日 22点7分5秒',
    '20201220 220705',
    '2020/12-20 22:07:05',
    '12/20 2020 22:07:05',
]

# 以下输出的结果均为 2020-12-20 22:07:05
for i in my_date:
    # get()方法用于解析时间,format()来格式化
    arrow.get(i, fmt).format('YYYY-MM-DD HH:mm:ss')

不过要注意,这里的正则表达式支持并不完整,但已经够用了。

上面仅仅是 arrow 模块一个很小的功能,它的强大远不止如此。

根据官方文档描述:

Arrow 是一个提供了更加合理和人性化的方法来创建、操作、格式化和转换日期、时间和时间戳的 Python 库。它实现了并更新 datetime 类型,弥补了其缺少的功能,另外提供一个API,用来支持许多常见的创建场景智能模块。简单地说,它能帮助你用更少的导入模块和代码来使用日期和时间。

Arrow 的命名来自物理学中的“时间箭头Arrow of time”,一定程度上受到 moment.js 和 requests 两个库的启发。

为啥要用 Arrow 来代替 Python 内置的时间模块?

Python 标准库和其他一些低层次的模块已经几乎完成了日期、时间和时区相关的所有功能,但它们的可用性不太好:

- 模块太多:datetime, time, calendar, dateutil, pytz 等
- 类型太多: date, time, datetime, tzinfo, timedelta, relativedelta 等
- 涉及时区和时间戳的转换太过繁琐,令人不爽。
- 时区问题太弱智
- ISO 8601 解析、时间间隔、人性化等相关函数功能不完善。

Arrow 的特性:

- 可以完全代替 datetime
- 支持 Python 2.7 到 3.9,持续更新中
- 默认使用 UTC 时区
- 在很多场景下使用起来超级简单
- 转换格式时支持相对偏移,包括周
- 自动格式和解析字符串
- 对 ISO 8601 的广泛支持
- 时区转换
- 时间戳可以作为属性
- .......

安装:

pip install -U arrow

用法示例:

import arrow

# 获取当前UTC格式时间
>>> utc = arrow.utcnow()
>>> utc
<Arrow [2013-05-11T21:23:58.970460+00:00]>

# 时间偏移
>>> utc = utc.shift(hours=-1)
>>> utc
<Arrow [2013-05-11T20:23:58.970460+00:00]>

# 根据时区获取当前时间
>>> local = utc.to('US/Pacific')
>>> local
<Arrow [2013-05-11T13:23:58.970460-07:00]>

# 转换为时间戳
>>> local.timestamp
1368303838

# 格式化,默认为 YYYY-MM-DD HH:mm:ss ZZ
>>> local.format()
'2013-05-11 13:23:58 -07:00'

# 按指定格式来格式化
>>> local.format('YYYY-MM-DD HH:mm:ss ZZ')
'2013-05-11 13:23:58 -07:00'

# 适用于人类阅读的时间格式,默认为英文
>>> local.humanize()
'an hour ago'

# 可指定语言,支持中文
>>> local.humanize(locale='zh_cn')
'4分钟前'

更多用法可参看 arrow 库的文档。

参考资料:

» 链接地址:https://wbt5.com/python-arrow.html »英雄不问来路,转载请注明出处。

Python 利用 Arrow 库转换时间格式》上有 2 条评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注