当前位置: 首页 > news >正文

Python Arrow库:告别datetime繁琐,优雅处理时间与时区

如果你用Python处理过时间,一定被datetime的“反人类”设计折磨过:想加个小时要手动算timedelta,处理时区得额外装pytz,格式化字符串要记一堆%Y%m%d符号……而**Arrow**库的出现,把时间处理变成了“一行代码的事”。

Arrow是Python中最流行的时间处理库之一,它基于datetime封装,但API更简洁、功能更强大——内置时区支持、一键格式化、人类可读时间、时间差计算等,让你彻底告别“时间处理焦虑”。

今天这篇博客,我们从“基础到实战”,用15+示例带你掌握Arrow的核心用法,让时间处理从此优雅高效。

一、为什么选Arrow?先看一组对比

同样是“获取当前上海时间,格式化为‘2024-05-20 14:30:00’”,看看datetime和Arrow的差距:

用datetime实现(繁琐)

from datetime import datetime
import pytz  # 需额外安装# 1. 获取当前UTC时间,转换为上海时区
sh_tz = pytz.timezone('Asia/Shanghai')
now = datetime.utcnow().replace(tzinfo=pytz.UTC).astimezone(sh_tz)
# 2. 格式化输出
formatted = now.strftime('%Y-%m-%d %H:%M:%S')
print(formatted)  # 2024-05-20 14:30:00

用Arrow实现(优雅)

import arrow# 一行搞定:获取上海时间 + 格式化
formatted = arrow.now('Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss')
print(formatted)  # 2024-05-20 14:30:00

仅一行代码,无需额外依赖(Arrow内置时区数据库),API直观到“见名知意”——这就是Arrow的魅力。

二、环境准备:5秒搞定安装

Arrow是第三方库,安装极其简单,直接用pip:

# 安装最新版Arrow
pip install arrow

验证安装是否成功:

 
import arrow
print(arrow.__version__)  # 输出当前版本,如1.3.0(确保≥1.0.0,功能更全)

三、基础用法:创建与转换Arrow对象

Arrow的核心是Arrow类,所有时间操作都围绕它展开。首先要掌握“如何创建Arrow对象”,以及“如何转换为其他类型(如datetime、字符串、时间戳)”。

1. 创建Arrow对象(5种常用方式)

import arrow# 1. 获取当前时间(带本地时区,默认系统时区)
local_now = arrow.now()
print("本地当前时间:", local_now)  # 如 2024-05-20T14:35:22.123456+08:00(+08:00是时区)# 2. 获取当前UTC时间(推荐用于存储,避免时区混乱)
utc_now = arrow.utcnow()
print("UTC当前时间:", utc_now)  # 如 2024-05-20T06:35:22.123456+00:00(+00:00是UTC)# 3. 从指定时区创建时间(常用场景:明确业务时区,如上海、纽约)
sh_now = arrow.now('Asia/Shanghai')  # 上海时区(东八区)
ny_now = arrow.now('America/New_York')  # 纽约时区(西五区)
print("上海时间:", sh_now)
print("纽约时间:", ny_now)# 4. 从字符串创建(自动解析格式,无需手动指定strftime)
time_str1 = "2024-05-20 14:30:00"
arrow1 = arrow.get(time_str1)
print("从字符串创建1:", arrow1)  # 2024-05-20T14:30:00+00:00(默认UTC,需手动指定时区)# 带时区的字符串
time_str2 = "2024-05-20T14:30:00+08:00"
arrow2 = arrow.get(time_str2)
print("从字符串创建2:", arrow2)  # 2024-05-20T14:30:00+08:00(自动识别时区)# 5. 从datetime对象转换(无缝兼容datetime)
from datetime import datetime
dt = datetime(2024, 5, 20, 14, 30)
arrow_from_dt = arrow.Arrow.fromdatetime(dt, tzinfo='Asia/Shanghai')
print("从datetime创建:", arrow_from_dt)  # 2024-05-20T14:30:00+08:00

关键提示:时区名称需符合IANA时区数据库(如Asia/Shanghai而非BeijingAmerica/New_York而非NewYork),可通过pytz.all_timezones查看所有合法时区。

2. 类型转换:Arrow ↔ 字符串/时间戳/datetime

Arrow对象可轻松转换为日常开发中常用的类型,无需复杂处理:

import arrow# 以“上海当前时间”为例
sh_now = arrow.now('Asia/Shanghai')  # 2024-05-20T14:40:00.123456+08:00# 1. 转换为字符串(默认ISO格式)
iso_str = sh_now.isoformat()
print("ISO格式字符串:", iso_str)  # 2024-05-20T14:40:00.123456+08:00# 2. 转换为自定义格式字符串(支持strftime所有格式符)
custom_str = sh_now.format('YYYY年MM月DD日 HH:mm:ss')
print("自定义格式:", custom_str)  # 2024年05月20日 14:40:00# 3. 转换为时间戳(秒级/毫秒级)
timestamp_sec = sh_now.timestamp()  # 秒级时间戳(整数)
timestamp_ms = sh_now.timestamp_ms()  # 毫秒级时间戳(整数)
print("秒级时间戳:", timestamp_sec)  # 1716211200
print("毫秒级时间戳:", timestamp_ms)  # 1716211200123# 4. 转换为datetime对象(带时区)
dt_with_tz = sh_now.datetime
print("带时区datetime:", dt_with_tz)  # 2024-05-20 14:40:00.123456+08:00# 转换为 naive datetime(无时区,谨慎使用)
dt_naive = sh_now.naive
print("无时区datetime:", dt_naive)  # 2024-05-20 14:40:00.123456

四、核心亮点:时区处理(Arrow的王牌功能)

datetime处理时区需要依赖pytz,且API繁琐;而Arrow**内置时区支持**,一行代码即可实现时区创建、转换、切换,彻底解决时区痛点。

1. 给Arrow对象添加时区

如果创建的Arrow对象是“无时区”的(如从字符串解析的默认UTC),可通过to()replace(tzinfo)添加时区:

import arrow# 1. 无时区对象(默认UTC)
arrow_utc = arrow.get("2024-05-20 14:30:00")  # 2024-05-20T14:30:00+00:00# 2. 转换为上海时区(本质:将UTC时间转换为上海时间,时间值会变)
arrow_sh = arrow_utc.to('Asia/Shanghai')
print("UTC→上海:", arrow_sh)  # 2024-05-20T22:30:00+08:00(UTC14点=上海22点)# 3. 直接添加时区(注意:不改变时间值,仅附加时区信息,谨慎使用)
arrow_naive = arrow.get("2024-05-20 14:30:00").naive  # 先转为无时区
arrow_add_tz = arrow.Arrow.fromdatetime(arrow_naive, tzinfo='Asia/Shanghai')
print("添加上海时区:", arrow_add_tz)  # 2024-05-20T14:30:00+08:00(时间值不变)

关键区别to()是“时区转换”(时间值随时区变化),fromdatetime(..., tzinfo)是“附加时区”(时间值不变),根据业务场景选择。

2. 时区之间的转换

任意两个时区之间的转换,只需调用to()方法指定目标时区:

import arrow# 1. 获取当前纽约时间
ny_now = arrow.now('America/New_York')  # 如 2024-05-20T02:45:00-04:00(西四区)# 2. 转换为上海时间
sh_now = ny_now.to('Asia/Shanghai')
print("纽约→上海:", sh_now)  # 2024-05-20T14:45:00+08:00(纽约2点=上海14点,时差12小时)# 3. 再转换为伦敦时间
london_now = sh_now.to('Europe/London')
print("上海→伦敦:", london_now)  # 2024-05-20T06:45:00+00:00(上海14点=伦敦6点,时差8小时)

3. UTC与本地时区的快速切换

开发中常需要“存储用UTC,展示用本地时区”,Arrow提供utcnow()now()快速切换:

import arrow# 1. 存储:获取UTC时间(推荐用于数据库存储,避免时区混乱)
utc_time = arrow.utcnow()
print("存储用UTC:", utc_time)  # 2024-05-20T06:50:00+00:00# 2. 展示:转换为本地时区(自动识别系统时区)
local_time = utc_time.to('local')
print("展示用本地时区:", local_time)  # 2024-05-20T14:50:00+08:00(若系统是上海时区)

五、实用操作:时间格式化与解析

Arrow的格式化和解析功能比datetime更灵活,支持自动识别格式、自定义格式,甚至非标准时间字符串。

1. 时间格式化(输出字符串)

除了前面提到的format(),Arrow还支持常用格式的快捷方法:

import arrowsh_now = arrow.now('Asia/Shanghai')  # 2024-05-20T15:00:00+08:00# 1. 标准格式
print("ISO格式:", sh_now.isoformat())  # 2024-05-20T15:00:00.123456+08:00
print("日期部分:", sh_now.date())  # 2024-05-20(返回date对象,可转字符串)
print("时间部分:", sh_now.time())  # 15:00:00.123456(返回time对象)# 2. 自定义格式(支持所有strftime符号,且兼容Python和Arrow扩展符号)
print("年-月-日 时:分:秒:", sh_now.format('YYYY-MM-DD HH:mm:ss'))  # 2024-05-20 15:00:00
print("带星期:", sh_now.format('YYYY-MM-DD HH:mm:ss dddd'))  # 2024-05-20 15:00:00 星期一
print("12小时制(带AM/PM):", sh_now.format('YYYY-MM-DD hh:mm:ss A'))  # 2024-05-20 03:00:00 PM

常用格式符YYYY(4位年)、MM(2位月)、DD(2位日)、HH(24小时制)、hh(12小时制)、mm(分)、ss(秒)、dddd(完整星期)、A(AM/PM)。

2. 时间解析(字符串→Arrow对象)

Arrow的get()方法能自动识别大多数时间格式,无需手动指定strftime,极大简化解析流程:

import arrow# 1. 自动识别标准格式(无需指定格式)
arrow1 = arrow.get("2024-05-20")
arrow2 = arrow.get("2024/05/20 15:30")
arrow3 = arrow.get("2024-05-20T15:30:00+08:00")
print("自动解析1:", arrow1)  # 2024-05-20T00:00:00+00:00
print("自动解析2:", arrow2)  # 2024-05-20T15:30:00+00:00
print("自动解析3:", arrow3)  # 2024-05-20T15:30:00+08:00# 2. 解析非标准格式(需指定格式符)
non_std_str = "2024年05月20日 15时30分"
arrow4 = arrow.get(non_std_str, 'YYYY年MM月DD日 HH时mm分')
print("解析非标准格式:", arrow4)  # 2024-05-20T15:30:00+00:00# 3. 解析时间戳(秒级/毫秒级)
timestamp_sec = 1716214200  # 对应2024-05-20 15:30:00(上海时区)
timestamp_ms = 1716214200123
arrow5 = arrow.get(timestamp_sec)
arrow6 = arrow.get(timestamp_ms)
print("解析秒级时间戳:", arrow5.to('Asia/Shanghai'))  # 2024-05-20T15:30:00+08:00
print("解析毫秒级时间戳:", arrow6.to('Asia/Shanghai'))  # 2024-05-20T15:30:00.123000+08:00

六、时间计算:加减、比较与差值

Arrow简化了时间的加减和比较操作,无需手动创建timedelta,API更直观。

1. 时间加减(shift()方法)

shift()方法可轻松加减年、月、日、时、分、秒,支持多单位同时操作:

import arrownow = arrow.now('Asia/Shanghai')  # 2024-05-20T16:00:00+08:00# 1. 加时间
one_hour_later = now.shift(hours=1)  # 1小时后
three_days_later = now.shift(days=3)  # 3天后
one_month_later = now.shift(months=1)  # 1个月后(自动处理月份天数,如5月20日→6月20日)
print("1小时后:", one_hour_later)  # 2024-05-20T17:00:00+08:00
print("3天后:", three_days_later)  # 2024-05-23T16:00:00+08:00
print("1个月后:", one_month_later)  # 2024-06-20T16:00:00+08:00# 2. 减时间(传负数)
one_hour_ago = now.shift(hours=-1)  # 1小时前
two_weeks_ago = now.shift(weeks=-2)  # 2周前
print("1小时前:", one_hour_ago)  # 2024-05-20T15:00:00+08:00
print("2周前:", two_weeks_ago)  # 2024-05-06T16:00:00+08:00# 3. 多单位同时加减
later = now.shift(days=1, hours=2, minutes=30)  # 1天2小时30分钟后
print("1天2小时30分后:", later)  # 2024-05-21T18:30:00+08:00

2. 时间比较(常规运算符)

Arrow对象支持直接用<>==等运算符比较,无需转换为时间戳:

import arrowtime1 = arrow.get("2024-05-20 16:00:00", tzinfo='Asia/Shanghai')
time2 = arrow.get("2024-05-20 17:00:00", tzinfo='Asia/Shanghai')
time3 = arrow.get("2024-05-20 16:00:00", tzinfo='Asia/Shanghai')# 1. 比较大小
print(time1 < time2)  # True(time1早于time2)
print(time1 > time2)  # False
print(time1 == time3)  # True(时间和时区都相同)# 2. 比较不同时区的时间(自动转换为同一时区后比较)
time4 = arrow.get("2024-05-20 08:00:00", tzinfo='UTC')  # UTC8点=上海16点
print(time1 == time4)  # True(自动转换时区后相等)

3. 计算时间差(total_seconds())

两个Arrow对象相减,得到arrow.arrow.Timedelta对象,可转换为秒、分钟、小时等:

import arrowstart = arrow.get("2024-05-20 16:00:00", tzinfo='Asia/Shanghai')
end = arrow.get("2024-05-20 18:30:00", tzinfo='Asia/Shanghai')# 1. 计算时间差
delta = end - start
print("时间差对象:", delta)  # 0:2:30:00.000000(天:时:分:秒)# 2. 转换为具体单位
print("总秒数:", delta.total_seconds())  # 9000.0(2.5小时=9000秒)
print("总分钟数:", delta.total_seconds() / 60)  # 150.0
print("小时数:", delta.hours)  # 2(注意:hours是整数部分,不包含分钟)
print("分钟数:", delta.minutes)  # 30

七、实战工具:人类可读时间与时间取整

Arrow提供了很多“人性化”工具方法,比如生成“2小时前”的字符串、将时间取整到小时/天,这些在日志展示、数据统计中非常实用。

1. 人类可读时间(humanize())

humanize()方法能将Arrow对象转换为“多久前/后”的人类可读字符串,支持多语言:

import arrownow = arrow.now('Asia/Shanghai')  # 2024-05-20T19:00:00+08:00# 1. 过去的时间
one_hour_ago = now.shift(hours=-1)
three_days_ago = now.shift(days=-3)
print("1小时前:", one_hour_ago.humanize())  # an hour ago
print("3天前:", three_days_ago.humanize())  # 3 days ago# 2. 未来的时间
two_weeks_later = now.shift(weeks=2)
print("2周后:", two_weeks_later.humanize())  # in 2 weeks# 3. 中文支持(需指定locale参数)
print("1小时前(中文):", one_hour_ago.humanize(locale='zh'))  # 1小时前
print("3天前(中文):", three_days_ago.humanize(locale='zh'))  # 3天前
print("2周后(中文):", two_weeks_later.humanize(locale='zh'))  # 2周后

支持的语言zh(中文)、en(英文)、ja(日文)、fr(法文)等,需确保系统安装对应语言包(一般默认支持中文)。

2. 时间取整(floor()/ceil())

将时间“向下取整”或“向上取整”到指定单位(如小时、天、月),常用于数据统计(如按小时汇总日志):

import arrownow = arrow.now('Asia/Shanghai')  # 2024-05-20T19:23:45+08:00# 1. 向下取整(floor():取到当前单位的起始时间)
floor_hour = now.floor('hour')  # 取整到小时
floor_day = now.floor('day')    # 取整到天(当天0点)
floor_month = now.floor('month')# 取整到月(当月1号0点)
print("向下取整到小时:", floor_hour)  # 2024-05-20T19:00:00+08:00
print("向下取整到天:", floor_day)    # 2024-05-20T00:00:00+08:00
print("向下取整到月:", floor_month)  # 2024-05-01T00:00:00+08:00# 2. 向上取整(ceil():取到当前单位的结束时间)
ceil_hour = now.ceil('hour')    # 取整到下一小时
ceil_day = now.ceil('day')      # 取整到明天0点
print("向上取整到小时:", ceil_hour)  # 2024-05-20T20:00:00+08:00
print("向上取整到天:", ceil_day)    # 2024-05-21T00:00:00+08:00

八、进阶实战:用Arrow处理日志时间

假设你有一份日志文件,每行日志的时间格式是“2024-05-20 19:30:00”(无时区),需要:

  1. 解析日志时间并添加上海时区;

  2. 筛选出“2024-05-20 19:00-20:00”之间的日志;

  3. 计算每条日志与当前时间的差值,生成“XX分钟前”的备注。

用Arrow实现这一需求,代码简洁高效:

import arrow# 模拟日志数据
logs = ["2024-05-20 18:50:00 - 用户A登录","2024-05-20 19:15:00 - 用户B操作订单","2024-05-20 19:45:00 - 用户C退出","2024-05-20 20:10:00 - 用户D登录"
]# 目标时间范围(2024-05-20 19:00-20:00 上海时区)
start_time = arrow.get("2024-05-20 19:00:00", tzinfo='Asia/Shanghai')
end_time = arrow.get("2024-05-20 20:00:00", tzinfo='Asia/Shanghai')
now = arrow.now('Asia/Shanghai')# 处理日志
print("筛选出19:00-20:00的日志:")
for log in logs:# 1. 提取日志时间字符串(前19个字符)time_str = log[:19]# 2. 解析时间并添加上海时区log_time = arrow.get(time_str, tzinfo='Asia/Shanghai')# 3. 筛选时间范围if start_time <= log_time < end_time:# 4. 计算与当前时间的差值(人类可读)time_diff = log_time.humanize(now, locale='zh')# 5. 输出结果print(f"{log} - {time_diff}")# 输出结果:
# 筛选出19:00-20:00的日志:
# 2024-05-20 19:15:00 - 用户B操作订单 - 45分钟前(假设当前是20:00)
# 2024-05-20 19:45:00 - 用户C退出 - 15分钟前

九、总结:为什么Arrow值得替代datetime?

  1. API更简洁:一行代码实现时间创建、时区转换、格式化,告别datetime的嵌套调用;

  2. 时区原生支持:无需依赖pytz,内置IANA时区数据库,轻松处理跨时区场景;

  3. 功能更丰富:人类可读时间、时间取整、自动解析格式等实用功能,覆盖90%+时间处理场景;

  4. 兼容性强:无缝转换为datetime、字符串、时间戳,可直接用于现有项目。

如果你还在为datetime的繁琐而头疼,不妨试试Arrow——它会让你发现:处理时间原来可以这么优雅!

最后:常用操作速查表

需求

Arrow实现

获取上海当前时间

arrow.now('Asia/Shanghai')

UTC时间转上海时间

arrow.utcnow().to('Asia/Shanghai')

时间格式化为“2024-05-20 14:30”

arrow_obj.format('YYYY-MM-DD HH:mm')

解析“2024年05月20日”为Arrow对象

arrow.get("2024年05月20日", 'YYYY年MM月DD日')

计算1小时后时间

arrow_obj.shift(hours=1)

生成“2小时前”的中文描述

arrow_obj.humanize(locale='zh')

时间向下取整到小时

arrow_obj.floor('hour')

http://www.dtcms.com/a/494258.html

相关文章:

  • SQL 处理问题(删除大表数据、查询慢、统计不准、锁超时)
  • 佛山外贸网站建设效果一个网站突然打不开
  • 中国建设网官方网站硅灰wordpress 表格边框
  • php做音乐网站17zwd一起做网站官网
  • 犀牛云做网站编辑上传网站建设文件
  • 装饰公司网站建站网站后台管理无法编辑
  • 网站建设中upl连接网站开发教案
  • 整站优化外包公司中国域名注册
  • 再网站里做商家店铺网页素材大宝库
  • 精湛的网站建设免费的企业宣传模板
  • 做网站在哪个地方买空间wordpress 图片展示插件
  • 网站域名维护有赞分销
  • 中邮保险网站wordpress主题游戏cms
  • 普兰店网站建设公司潍坊专业环保设备
  • 惠济区建设局网站做7寸照片的网站
  • 论文中引用网站怎么写网站的代理页面怎么做
  • 用什么做网站方便网页认证
  • 暖色调网页设计网站创意广告设计网站
  • 百度网站链接优化网站排名方法
  • 四川通管局网站贵阳市建设城乡规划局网站
  • 长沙做网站比较好的公司网站模板论坛
  • 企业网站seo案例单页网站下载
  • 国外建站系统天元建设集团有限公司注册资金
  • 中山建网站推荐网站不续费
  • 做资源网站怎么不封百度地图推广一年多少钱
  • 徐州做网站的公司有哪些wordpress文章分页共多少页
  • 北海公司做网站创客贴网站做海报技能
  • 电子商务物流网站建设规划方案大气手机网站模板
  • 个人可以做商城网站psd素材
  • 有没有专门做纸箱的网站台州 wordpress