欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
AtomGit 仓库地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_python_numpy
1. 环境搭建:
本文介绍在鸿蒙 PC+CodeArts IDE 搭建 Python 开发环境。借助鸿蒙专属包管理器 Harmonybrew 安装适配版 Python,搭配 ohos-pip-autosign 自动签名工具,解决系统对动态库的签名限制。通过虚拟环境隔离依赖,以 NumPy 完成安装与脚本测试,成功解决权限报错,搭建出可用的 Python 开发环境。
可以参考以下文章OpenHarmony 鸿蒙 PC + CodeArts IDE 实现 Python开发完整开发环境搭建指南
Python Arrow 库完整详解 + 全套实战 Demo
一、Arrow 是什么
arrow是 Python 第三方人性化时间处理库,对原生datetime、time、calendar做了高度封装,解决原生日期 API 繁琐、时区处理麻烦、格式化代码冗长的痛点。
原生 datetime 痛点:
- 格式化、时间差、时区转换代码量大
- 时间加减、上月/下周/季度获取逻辑复杂
- 解析各种不规则日期字符串非常麻烦
- 时区操作容易出错
Arrow 核心优势:
- 链式调用,一行代码搞定时间操作
- 内置大量人性化时间语义:
shift(months=-1)上月、ceil('day')当天结束 - 自动兼容各种日期字符串解析
- 完善时区、时间戳、本地时间/UTC互转
- 人性化相对时间输出:
2小时前、3天内 - 支持格式化、截取、区间、季度、周操作
二、安装
pip3installarrow三、核心基础API总览
importarrow# 1. 获取当前时间(本地/UTC)arrow.now()# 本地当前时间arrow.utcnow()# UTC标准时间# 2. 构造指定时间arrow.Arrow(2026,6,17,12,30)arrow.get("2026-06-17 15:20:10")# 3. 时间戳互转arrow.get(1781712000)# 秒级时间戳arrow.get(1781712000000)# 毫秒时间戳# 4. 格式化输出t.format("YYYY-MM-DD HH:mm:ss")# 5. 时间偏移(加减)t.shift(days=1)# 加1天t.shift(months=-1)# 减1个月# 6. 取边界t.floor('day')# 当天0点t.ceil('hour')# 当前小时最后一秒# 7. 相对时间t.humanize(locale='zh-cn')# 中文:3小时前完整可运行 Demo(分场景)
Demo1:获取当前时间、格式化、时间戳转换
importarrow# 1. 当前本地时间now=arrow.now()print("本地完整时间对象:",now)print("当前年月日时分秒:",now.format("YYYY-MM-DD HH:mm:ss"))print("当前日期:",now.format("YYYY-MM-DD"))print("当前时间:",now.format("HH:mm:ss"))print("当前年份季度:",now.format("YYYY-Q"))# 2. UTC 零时区时间utc_now=arrow.utcnow()print("\nUTC时间:",utc_now.format("YYYY-MM-DD HH:mm:ss"))# 3. 转秒级时间戳ts_sec=now.timestamp()print("秒级时间戳:",ts_sec)# 毫秒时间戳ts_ms=int(now.timestamp()*1000)print("毫秒时间戳:",ts_ms)# 4. 时间戳还原时间对象t1=arrow.get(ts_sec)t2=arrow.get(ts_ms/1000)print("\n时间戳还原:",t1.format("YYYY-MM-DD HH:mm:ss"))# 5. 自定义格式化模板print("年月中文:",now.format("YYYY年MM月DD日 HH点mm分"))Demo2:解析任意格式日期字符串(最强功能)
无需写复杂匹配模板,自动识别各种日期文本
importarrow# 各种不规则字符串自动解析time_str_list=["2026-06-17","2026/06/17 14:30","20260617152010","17 Jun 2026","2026-06-17T12:30:00+08:00","2026年06月17日 16点20分"]forsintime_str_list:t=arrow.get(s)print(f"原字符串:{s:<30}→ 标准格式:{t.format('YYYY-MM-DD HH:mm:ss')}")# 指定格式解析(严格匹配)t=arrow.get("17|06|2026","DD|MM|YYYY")print("\n自定义分隔符解析:",t.format("YYYY-MM-DD"))Demo3:时间偏移(加减天/月/年/小时)
importarrow now=arrow.now()print("现在:",now.format("YYYY-MM-DD HH:mm:ss"))# 加1天t1=now.shift(days=1)print("明天:",t1.format("YYYY-MM-DD"))# 减3天t2=now.shift(days=-3)print("3天前:",t2.format("YYYY-MM-DD"))# 上个月、下个月last_month=now.shift(months=-1)next_month=now.shift(months=1)print("上月:",last_month.format("YYYY-MM"))print("下月:",next_month.format("YYYY-MM"))# 去年、明年last_year=now.shift(years=-1)print("去年今日:",last_year.format("YYYY-MM-DD"))# 小时、分钟、秒偏移add_2h=now.shift(hours=2)sub_30m=now.shift(minutes=-30)print("2小时后:",add_2h.format("HH:mm"))print("30分钟前:",sub_30m.format("HH:mm"))# 周偏移next_week=now.shift(weeks=1)print("下周今天:",next_week.format("YYYY-MM-DD"))Demo4:取区间边界(当天0点、当月首尾、季度)
importarrow now=arrow.now()# 当天零点 / 当天23:59:59day_start=now.floor("day")day_end=now.ceil("day")print("今日0点:",day_start.format("YYYY-MM-DD HH:mm:ss"))print("今日结束:",day_end.format("YYYY-MM-DD HH:mm:ss"))# 当月第一天、当月最后一天month_start=now.floor("month")month_end=now.ceil("month")print("\n本月第一天:",month_start.format("YYYY-MM-DD"))print("本月最后一天:",month_end.format("YYYY-MM-DD"))# 季度首尾quarter_start=now.floor("quarter")quarter_end=now.ceil("quarter")print("\n本季度起始:",quarter_start.format("YYYY-MM-DD"))print("本季度结束:",quarter_end.format("YYYY-MM-DD"))# 当年起始year_start=now.floor("year")print("今年第一天:",year_start.format("YYYY-MM-DD"))Demo5:人性化相对时间(中文:几分钟前/几天内)
报表、日志、消息列表最常用
importarrow# 构造几个时间点t1=arrow.now().shift(minutes=-5)t2=arrow.now().shift(hours=-3)t3=arrow.now().shift(days=-2)t4=arrow.now().shift(weeks=-1)t5=arrow.now().shift(months=-2)# locale='zh-cn' 输出中文print("5分钟前:",t1.humanize(locale="zh-cn"))print("3小时前:",t2.humanize(locale="zh-cn"))print("2天前:",t3.humanize(locale="zh-cn"))print("1周前:",t4.humanize(locale="zh-cn"))print("2个月前:",t5.humanize(locale="zh-cn"))# 未来时间future=arrow.now().shift(days=3)print("3天后:",future.humanize(locale="zh-cn"))Demo6:时间比较、区间判断、计算时间差
importarrow t1=arrow.get("2026-01-01")t2=arrow.get("2026-06-17")now=arrow.now()# 大小比较print("t1 < t2:",t1<t2)print("t2 > t1:",t2>t1)print("相等:",t1==t2)# 判断是否在区间内start=arrow.get("2026-01-01")end=arrow.get("2026-12-31")print("now 在2026区间:",start<=now<=end)# 计算相差天数、小时、秒diff_days=(t2-t1).days diff_seconds=(t2-t1).total_seconds()print(f"\nt1到t2相差天数:{diff_days}")print(f"相差总秒数:{diff_seconds}")# 精确差值delta=t2-t1print("差值对象天:",delta.days)print("差值总秒:",delta.total_seconds())Demo7:时区转换(UTC ↔ 北京时间Asia/Shanghai)
处理接口UTC时间、国际时间必备
importarrow# UTC时间转北京时间utc_t=arrow.utcnow()cn_t=utc_t.to("Asia/Shanghai")print("UTC时间:",utc_t.format("YYYY-MM-DD HH:mm:ss"))print("北京时间:",cn_t.format("YYYY-MM-DD HH:mm:ss"))# 本地时间转UTClocal=arrow.now("Asia/Shanghai")back_utc=local.to("UTC")print("\n本地转UTC:",back_utc.format("YYYY-MM-DD HH:mm:ss"))# 指定时区构造时间ny_t=arrow.now("America/New_York")print("纽约当前时间:",ny_t.format("YYYY-MM-DD HH:mm:ss"))Demo8:常用业务工具封装(可直接复制到项目)
importarrowclassArrowTimeUtil:@staticmethoddefget_now_str(fmt="YYYY-MM-DD HH:mm:ss"):"""获取当前格式化字符串"""returnarrow.now().format(fmt)@staticmethoddefget_ts_ms():"""获取毫秒时间戳"""returnint(arrow.now().timestamp()*1000)@staticmethoddefstr_to_time(date_str,fmt="YYYY-MM-DD HH:mm:ss"):"""日期字符串转Arrow对象"""returnarrow.get(date_str,fmt)@staticmethoddefget_day_range(offset=0):"""获取某天的起止时间 offset=0今天 -1昨天 1明天"""target=arrow.now().shift(days=offset)start=target.floor("day")end=target.ceil("day")returnstart.format(),end.format()@staticmethoddefget_month_range(offset=0):"""获取某月起止 offset=0本月 -1上月"""target=arrow.now().shift(months=offset)start=target.floor("month")end=target.ceil("month")returnstart.format("YYYY-MM-DD"),end.format("YYYY-MM-DD")@staticmethoddefhuman_cn(time_obj):"""输出中文相对时间"""returntime_obj.humanize(locale="zh-cn")if__name__=="__main__":util=ArrowTimeUtil()print("当前时间:",util.get_now_str())print("毫秒时间戳:",util.get_ts_ms())print("今日区间:",util.get_day_range(0))print("上月区间:",util.get_month_range(-1))t=arrow.now().shift(hours=-2)print("相对时间:",util.human_cn(t))这是一套基于 Pythonarrow库封装的日期时间工具类,统一处理时间格式化、时间戳、日期区间、中文相对时间,全部静态方法,不用实例化就能调用,日常业务接口、日志、数据库时间处理非常好用。
1. 头部导入
importarrowarrow是 Python 第三方时间库,比原生datetime更简洁,支持时间偏移、格式化、本地化、时间戳转换,安装命令:
pipinstallarrow2. 工具类定义ArrowTimeUtil
全部方法加@staticmethod静态装饰器,调用方式:ArrowTimeUtil.方法名(),不需要创建对象。
get_now_str() 获取当前格式化时间字符串
@staticmethoddefget_now_str(fmt="YYYY-MM-DD HH:mm:ss"):"""获取当前格式化字符串"""returnarrow.now().format(fmt)arrow.now():获取当前本地时间 Arrow 对象- 默认格式
YYYY-MM-DD HH:mm:ss(年-月-日 时:分:秒) - 支持自定义传入 fmt,例如
get_now_str("YYYY-MM-DD")只返回日期
get_ts_ms() 获取毫秒时间戳
@staticmethoddefget_ts_ms():"""获取毫秒时间戳"""returnint(arrow.now().timestamp()*1000).timestamp()返回秒级浮点数,乘以1000转为毫秒int()去掉小数,返回整数毫秒戳,前后端交互常用
str_to_time() 时间字符串转 Arrow 对象
@staticmethoddefstr_to_time(date_str,fmt="YYYY-MM-DD HH:mm:ss"):"""日期字符串转Arrow对象"""returnarrow.get(date_str,fmt)把文本时间(如"2026-06-23 12:30:00")解析成可运算的 Arrow 时间对象,后续可以做加减、对比、格式化。
get_day_range(offset=0) 获取某一天的开始、结束时间
@staticmethoddefget_day_range(offset=0):"""获取某天的起止时间 offset=0今天 -1昨天 1明天"""target=arrow.now().shift(days=offset)start=target.floor("day")end=target.ceil("day")returnstart.format(),end.format()shift(days=offset):时间偏移
offset=0 → 今天;offset=-1 → 昨天;offset=1 → 明天.floor("day"):当天零点(00:00:00).ceil("day"):当天23:59:59.999- 返回两个格式化字符串,用于数据库查询当天数据区间
get_month_range(offset=0) 获取某月起止日期
@staticmethoddefget_month_range(offset=0):"""获取某月起止 offset=0本月 -1上月"""target=arrow.now().shift(months=offset)start=target.floor("month")end=target.ceil("month")returnstart.format("YYYY-MM-DD"),end.format("YYYY-MM-DD")逻辑和日期区间一致,单位换成月份,返回格式只有年月日,常用于月度统计报表。
human_cn() 生成中文相对时间
@staticmethoddefhuman_cn(time_obj):"""输出中文相对时间"""returntime_obj.humanize(locale="zh-cn")接收一个 Arrow 时间对象,自动计算和当前时间的差值,输出人性化中文:
如2小时前、3天前、1个月前,适合消息列表、操作日志展示。
3. 主函数测试代码
if__name__=="__main__":util=ArrowTimeUtil()print("当前时间:",util.get_now_str())print("毫秒时间戳:",util.get_ts_ms())print("今日区间:",util.get_day_range(0))print("上月区间:",util.get_month_range(-1))t=arrow.now().shift(hours=-2)print("相对时间:",util.human_cn(t))if __name__ == "__main__代表直接运行该文件时执行测试:
- 打印当前标准时间字符串
- 打印毫秒时间戳
- 打印今天0点~明天0点区间
- 打印上月第一天到当月第一天区间
- 构造2小时前的时间,输出中文“2小时前”
整体使用场景总结
这套工具统一封装高频时间操作,项目中不用重复写时间转换代码:
- 接口返回格式化时间
- 前后端毫秒时间戳交互
- 数据库按天/按月筛选数据
- 日志、消息展示人性化中文时间差
四、典型业务使用场景
- 接口日志打印:自动格式化、毫秒时间戳
- 筛选时间区间:查询今日、昨日、本月、上月数据
- 前端传参解析:自动识别各种不规则日期字符串
- 消息创建时间展示:
5分钟前、3天前人性化显示 - 跨时区项目:UTC时间与本地时区互转
- 定时任务:快速计算N天/月前后执行时间
- 报表统计:季度、月度、年度时间边界快速获取
五、对比原生 datetime 优势示例
原生写法(繁琐)
fromdatetimeimportdatetime,timedeltafromdateutil.relativedeltaimportrelativedelta now=datetime.now()# 取上月last_month=now-relativedelta(months=1)print(last_month.strftime("%Y-%m"))Arrow一行搞定
importarrowprint(arrow.now().shift(months=-1).format("YYYY-MM"))六、注意事项
- 解析模糊日期字符串时,如果格式混乱,建议传入第二个参数指定模板严格解析,避免歧义;
humanize中文需传入locale="zh-cn",默认英文;- 时区名称标准写法:
Asia/Shanghai,不要写GMT+8; - 时间差相减返回
timedelta对象,用.days取天数、.total_seconds()取总秒; - 存储数据库推荐格式化
YYYY-MM-DD HH:mm:ss或毫秒时间戳,可读性高。