鸿蒙PC搭配 ohos-pip-autosign 自动签名工具,完成三方库适配python-dateutil 超全实战教程|解决 datetime 年月加减、自动解析日期、周期计算
欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
AtomGit 仓库地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_python_numpy
本文介绍在鸿蒙 PC+CodeArts IDE 搭建 Python 开发环境。借助鸿蒙专属包管理器 Harmonybrew 安装适配版 Python,搭配 ohos-pip-autosign 自动签名工具,解决系统对动态库的签名限制。通过虚拟环境隔离依赖,以 NumPy 完成安装与脚本测试,成功解决权限报错,搭建出可用的 Python 开发环境。
可以参考OpenHarmony 鸿蒙 PC + CodeArts IDE 实现 Python开发完整开发环境搭建指南
python-dateutil 完整教程(大量无报错示例)
一、库介绍
1. 作用
python-dateutil 是 Python 超强日期时间扩展库,弥补标准库 datetime 功能缺失,提供日期解析、相对时间、时区、周期、工作日、月份偏移等能力。
原生 datetime 只能做简单加减,dateutil 可以轻松实现:“下个月、下周一、去年、3个月前、每个月最后一天、自动识别任意格式日期字符串”。
核心能力
- 万能日期解析 parser.parse:自动识别几乎所有格式日期字符串,无需手动写格式模板;
- relativedelta 相对时间偏移:支持按年/月/日/周/时/分/秒增减,解决原生datetime不能直接加减月份的痛点;
- rrule 周期生成:生成每日/每周/每月/每年重复日期(日程、定时任务);
- 工作日计算 rrule + MO/TU/WE/TH/FR:获取下周一、本月所有工作日、排除周末;
- 时区 tzoffset/tzutc:自定义时区、UTC时间转换;
- 月份首尾、季度、节假日简易计算;
- 兼容 datetime.date / datetime.datetime 对象无缝互操作。
业务场景
- 爬虫:自动解析网页杂乱格式的发布时间;
- 后台统计:近7天、近30天、上月、去年数据筛选;
- 日程系统:生成每周重复提醒、每月账单日;
- 报表:获取每月第一天/最后一天、季度起止;
- 日志处理:解析不规则时间字符串;
- 定时脚本:批量生成未来执行时间点。
安装命令
pip install python-dateutil

完整大篇幅示例代码 dateutil_demo.py
from datetime import datetime, date, timedelta
from dateutil import parser, rrule
# 修复:单独导入relativedelta类、星期枚举
from dateutil.relativedelta import relativedelta, MO, TU, WE, TH, FR, SA, SU
from dateutil.tz import tzutc, tzoffset
# 基准测试时间
now_dt = datetime(2026, 6, 19, 14, 30, 15)
now_date = date(2026, 6, 19)
# -------------------------- 示例1:万能日期字符串自动解析 parser.parse --------------------------
def demo_parser():
print("===== 示例1:自动解析任意格式日期字符串 parser.parse =====")
time_str_list = [
"2026-06-19",
"2026/06/19 14:30",
"19/06/2026",
"Jun 19, 2026",
"2026-06-19 14:30:15",
"19 June 2026 2pm",
"20260619",
"6/19/26",
"2026-06-19T14:30:15Z"
]
for s in time_str_list:
try:
dt = parser.parse(s, fuzzy=True)
print(f"原始:{s:<30} → 解析:{dt}")
except Exception as e:
print(f"原始:{s:<30} → 解析失败:{e}")
print("\n")
# -------------------------- 示例2:relativedelta 相对时间加减(核心,原生timedelta无法按月) --------------------------
def demo_relativedelta_basic():
print("===== 示例2:relativedelta 年月日时分秒偏移计算 =====")
base = now_dt
# 加1年
next_year = base + relativedelta(years=1)
# 减2个月
two_month_ago = base - relativedelta(months=2)
# 加3周
three_week_later = base + relativedelta(weeks=3)
# 加10天5小时
complex_add = base + relativedelta(days=10, hours=5)
# 去年同一天
last_year = base + relativedelta(years=-1)
print(f"基准时间:{base}")
print(f"加1年:{next_year}")
print(f"减2个月:{two_month_ago}")
print(f"加3周:{three_week_later}")
print(f"加10天5小时:{complex_add}")
print(f"去年同日:{last_year}")
print("\n")
# -------------------------- 示例3:relativedelta 跳转本月/上月第一天、最后一天 --------------------------
def demo_month_start_end():
print("===== 示例3:获取当月、上月、下月第一天/最后一天 =====")
base = now_dt
# 当月第一天
month_first = base + relativedelta(day=1)
# 当月最后一天
month_last = base + relativedelta(months=1, day=1) - relativedelta(days=1)
# 上月第一天
last_month_first = base - relativedelta(months=1, day=1)
# 上月最后一天
last_month_last = base + relativedelta(day=1) - relativedelta(days=1) - relativedelta(months=1)
print(f"基准:{base.date()}")
print(f"本月第一天:{month_first.date()}")
print(f"本月最后一天:{month_last.date()}")
print(f"上月第一天:{last_month_first.date()}")
print(f"上月最后一天:{last_month_last.date()}")
print("\n")
# -------------------------- 示例4:relativedelta 跳转星期:下周一、上周五 --------------------------
def demo_weekday_jump():
print("===== 示例4:按星期跳转:下周一、上周五、本月第一个周二 =====")
base = now_dt
# 下周一
next_monday = base + relativedelta(weekday=MO(+1))
# 上周五
last_friday = base + relativedelta(weekday=FR(-1))
# 本月第一个周二
first_tue_month = base + relativedelta(day=1, weekday=TU(1))
print(f"基准:{base.date()}")
print(f"下周一:{next_monday.date()}")
print(f"上周五:{last_friday.date()}")
print(f"本月第一个周二:{first_tue_month.date()}")
print("\n")
# -------------------------- 示例5:rrule 生成周期日期:每日、每周、每月重复 --------------------------
def demo_rrule_cycle():
print("===== 示例5:rrule 生成周期重复日期(日程/定时任务) =====")
start = now_dt
# 生成未来5天,每天
daily_list = list(rrule.rrule(rrule.DAILY, count=5, dtstart=start))
print("未来5天每日:")
for d in daily_list:
print(" ", d.date())
# 未来4周,每周一
weekly_mo = list(rrule.rrule(rrule.WEEKLY, count=4, dtstart=start, byweekday=MO))
print("\n未来4个周一:")
for d in weekly_mo:
print(" ", d.date())
# 未来3个月,每月1号
monthly_1 = list(rrule.rrule(rrule.MONTHLY, count=3, dtstart=start, bymonthday=1))
print("\n未来3个月每月1号:")
for d in monthly_1:
print(" ", d.date())
print("\n")
# -------------------------- 示例6:计算两个日期差值(年/月/日) --------------------------
def demo_date_diff():
print("===== 示例6:计算两个时间间隔,精确到年月(timedelta只能算天) =====")
d1 = datetime(2024, 3, 10)
d2 = datetime(2026, 6, 19)
diff = relativedelta(d2, d1)
print(f"起始:{d1} 结束:{d2}")
print(f"间隔:{diff.years}年 {diff.months}月 {diff.days}天")
print("\n")
# -------------------------- 示例7:工作日筛选,排除周末,获取本月所有工作日 --------------------------
def demo_workday_filter():
print("===== 示例7:筛选本月所有工作日(排除周六周日) =====")
month_start = now_dt + relativedelta(day=1)
month_end = now_dt + relativedelta(months=1, day=1) - relativedelta(days=1)
# 生成当月所有日期,仅保留周一至周五
workdays = list(rrule.rrule(
rrule.DAILY,
dtstart=month_start,
until=month_end,
byweekday=(MO, TU, WE, TH, FR)
))
print(f"本月工作日列表:")
for d in workdays:
print(" ", d.date(), d.strftime("%A"))
print(f"\n本月工作日总数:{len(workdays)}")
print("\n")
# -------------------------- 示例8:时区处理 UTC、自定义时区偏移 --------------------------
def demo_timezone():
print("===== 示例8:UTC时区、自定义时区偏移转换 =====")
utc_now = datetime.now(tzutc())
# UTC+8 东八区
tz_cn = tzoffset("UTC+8", 8 * 3600)
cn_time = utc_now.astimezone(tz_cn)
print(f"UTC 时间:{utc_now}")
print(f"UTC+8 北京时间:{cn_time}")
print("\n")
# -------------------------- 示例9:季度起止日期计算 --------------------------
def demo_quarter():
print("===== 示例9:获取当前季度、上一季度起止日期 =====")
base = now_dt
quarter = (base.month - 1) // 3
# 本季度第一个月
q_start_month = quarter * 3 + 1
q_start = base + relativedelta(month=q_start_month, day=1)
q_end = q_start + relativedelta(months=3) - relativedelta(days=1)
print(f"当前时间:{base.date()}")
print(f"本季度起始:{q_start.date()}")
print(f"本季度结束:{q_end.date()}")
print("\n")
# -------------------------- 示例10:模糊解析、忽略无关文字 fuzzy --------------------------
def demo_fuzzy_parse():
print("===== 示例10:fuzzy模糊解析,忽略无关中文/符号 =====")
text = "发布时间:2026-06-19 14:30 来自官网"
dt = parser.parse(text, fuzzy=True)
print(f"原文:{text}")
print(f"提取日期:{dt}")
text2 = "更新于 20/06/2026 10:22 浏览123次"
dt2 = parser.parse(text2, fuzzy=True)
print(f"原文:{text2}")
print(f"提取日期:{dt2}")
print("\n")
# -------------------------- 统一入口执行所有示例 --------------------------
def run_all():
demo_parser()
demo_relativedelta_basic()
demo_month_start_end()
demo_weekday_jump()
demo_rrule_cycle()
demo_date_diff()
demo_workday_filter()
demo_timezone()
demo_quarter()
demo_fuzzy_parse()
print("🎉 python-dateutil 全部示例执行完成,无报错")
if __name__ == "__main__":
run_all()

一、头部导入与常量定义
from datetime import datetime, date, timedelta
from dateutil import parser, rrule
from dateutil.relativedelta import relativedelta, MO, TU, WE, TH, FR, SA, SU
from dateutil.tz import tzutc, tzoffset
# 基准测试时间
now_dt = datetime(2026, 6, 19, 14, 30, 15)
now_date = date(2026, 6, 19)
- 原生datetime:Python自带基础日期对象,作为所有计算载体;
- parser:万能日期字符串解析器,自动识别千余种日期格式;
- rrule:周期日期生成器,生成每日/每周/每月重复时间序列;
- relativedelta:核心相对时间计算类,解决原生timedelta不能加减年月的痛点;
- MO~SU:周一到周日的星期枚举,用于筛选工作日、跳转指定星期;
- tzutc/tzoffset:时区工具,UTC标准时区、自定义时区偏移(北京时间UTC+8);
now_dt/now_date:固定基准测试时间,保证每次运行结果统一,不受系统实时日期干扰。
示例1:万能日期自动解析 parser.parse
def demo_parser():
time_str_list = [
"2026-06-19","2026/06/19 14:30","19/06/2026","Jun 19, 2026",
"2026-06-19 14:30:15","19 June 2026 2pm","20260619","6/19/26","2026-06-19T14:30:15Z"
]
for s in time_str_list:
try:
dt = parser.parse(s, fuzzy=True)
print(f"原始:{s:<30} → 解析:{dt}")
except Exception as e:
print(f"原始:{s:<30} → 解析失败:{e}")
核心作用
原生strptime必须手动匹配格式,格式写错直接崩溃;parser.parse自动识别任意主流日期写法。
fuzzy=True:忽略字符串中无关文字、符号(后面示例10单独演示中文混杂文本);- 支持横杠、斜杠、英文月份、数字紧凑格式、ISO标准UTC时间;
业务场景
爬虫抓取网页杂乱发布时间、日志不规则时间字符串解析。
示例2:relativedelta 相对时间偏移(库最核心能力)
def demo_relativedelta_basic():
base = now_dt
next_year = base + relativedelta(years=1)
two_month_ago = base - relativedelta(months=2)
three_week_later = base + relativedelta(weeks=3)
complex_add = base + relativedelta(days=10, hours=5)
last_year = base + relativedelta(years=-1)
关键优势
原生timedelta只支持天/时/分/秒,不能直接加减月份、年份,遇到2月、大小月、闰年直接报错;relativedelta自动处理历法规则:
years=1加1年,years=-1上一年;months=2加减月份,自动适配28/29/30/31天;- 支持多参数组合:同时加天数、小时;
业务场景
后台统计:近3个月、去年同期、下月报表时间范围计算。
示例3:获取当月/上月第一天、最后一天
def demo_month_start_end():
base = now_dt
month_first = base + relativedelta(day=1)
month_last = base + relativedelta(months=1, day=1) - relativedelta(days=1)
last_month_first = base - relativedelta(months=1, day=1)
last_month_last = base + relativedelta(day=1) - relativedelta(days=1) - relativedelta(months=1)
逻辑说明
day=1:强制跳转到当月1号;- 下月1号再减1天 = 当月最后一天,自动兼容大小月;
- 同理算出上月起止;
业务场景
月度报表、账单统计、按月数据筛选。
示例4:按星期跳转:下周一、上周五、当月第N个周二
def demo_weekday_jump():
base = now_dt
next_monday = base + relativedelta(weekday=MO(+1))
last_friday = base + relativedelta(weekday=FR(-1))
first_tue_month = base + relativedelta(day=1, weekday=TU(1))
参数规则:
MO(+1):下一个周一;FR(-1):上一个周五;TU(1):当月第一个周二;
业务场景
排班系统、每周定时任务、信用卡每月固定还款日。
示例5:rrule 生成周期重复日期
def demo_rrule_cycle():
start = now_dt
daily_list = list(rrule.rrule(rrule.DAILY, count=5, dtstart=start))
weekly_mo = list(rrule.rrule(rrule.WEEKLY, count=4, dtstart=start, byweekday=MO))
monthly_1 = list(rrule.rrule(rrule.MONTHLY, count=3, dtstart=start, bymonthday=1))
rrule是重复日期生成器,类似Linux crontab时间生成:
DAILY每日、WEEKLY每周、MONTHLY每月;count=5生成5个日期停止;dtstart起始时间;byweekday指定星期、bymonthday指定每月几号;
业务场景
日程提醒、定时备份、周期性批量任务。
示例6:两个日期精确拆分间隔(年/月/日)
def demo_date_diff():
d1 = datetime(2024, 3, 10)
d2 = datetime(2026, 6, 19)
diff = relativedelta(d2, d1)
print(f"间隔:{diff.years}年 {diff.months}月 {diff.days}天")
原生timedelta只能算出总天数,无法拆分几年几个月;relativedelta(结束时间, 起始时间) 自动拆分年、月、日三段间隔;
业务场景
计算用户注册时长、员工工龄、订单存续周期。
示例7:筛选当月所有工作日(排除周六周日)
def demo_workday_filter():
month_start = now_dt + relativedelta(day=1)
month_end = now_dt + relativedelta(months=1, day=1) - relativedelta(days=1)
workdays = list(rrule.rrule(
rrule.DAILY, dtstart=month_start, until=month_end, byweekday=(MO, TU, WE, TH, FR)
))
- 生成当月全部日期;
byweekday=(MO, TU, WE, TH, FR)只保留周一到周五;
业务场景
考勤统计、薪资核算、工作日业务排期。
示例8:时区转换 UTC / UTC+8 北京时间
def demo_timezone():
utc_now = datetime.now(tzutc())
tz_cn = tzoffset("UTC+8", 8 * 3600)
cn_time = utc_now.astimezone(tz_cn)
tzutc():标准零时区;tzoffset(name, 秒):自定义时区,东八区偏移8*3600秒;astimezone():时区互相转换;
业务场景
海外接口日志、多时区后台系统、国际化时间展示。
示例9:季度起止日期计算
def demo_quarter():
base = now_dt
quarter = (base.month - 1) // 3
q_start_month = quarter * 3 + 1
q_start = base + relativedelta(month=q_start_month, day=1)
q_end = q_start + relativedelta(months=3) - relativedelta(days=1)
计算逻辑:
- 月份除以3向下取整,判断属于第几季度;
- 算出本季度第一个月,取当月1号为季度起始;
- 加3个月再减1天得到季度最后一天;
业务场景
季度财报、季度数据统计、季度活动排期。
示例10:fuzzy 模糊提取混杂文本里的日期
def demo_fuzzy_parse():
text = "发布时间:2026-06-19 14:30 来自官网"
dt = parser.parse(text, fuzzy=True)
开启fuzzy=True后,自动忽略文字、中文、符号,只提取数字日期部分;
业务场景
爬虫直接提取网页混杂文案中的发布时间,不用手写正则。
统一入口 run_all()
依次执行上面10个场景示例,最后打印执行完成;
顶层代码if __name__ == "__main__"保证只有直接运行文件时才执行全部逻辑,被其他脚本导入时不会自动执行。
整体库核心价值总结
- 解决原生datetime硬伤:原生无法按月/年偏移,大小月、闰年计算极易出错;
- 日期解析零模板:不用手动写时间格式,自动识别各类字符串;
- 周期、工作日、季度、月度统计一站式工具,报表/后台高频需求一行代码实现;
- 时区、时间间隔、文本模糊提取覆盖爬虫、后端、自动化脚本全场景;
- 纯Python实现,无二进制依赖,任意Linux/鸿蒙/Windows环境直接运行。
逐段功能详细讲解
1. parser.parse 万能日期解析
无需手动定义 strftime 格式模板,自动识别千余种日期写法;fuzzy=True 可以忽略前后无关文字(爬虫网页提取时间神器)。
原生datetime.strptime 格式写错直接崩溃,dateutil容错极强。
2. relativedelta 相对时间(核心亮点)
标准库 timedelta 只能加减天时分秒,不能直接加减月份、年份(2月加1个月会报错、大小月错乱);relativedelta 自动处理大小月、闰年、跨年,完美解决统计“近30天、上月、去年”场景。
参数:years/months/weeks/days/hours/minutes/seconds,负数代表往前偏移。
3. 月份首尾快速获取
报表统计高频需求:每月第一天、最后一天,无需判断28/29/30/31号,一行代码算出。
4. 按星期跳转 MO/TU/WE/TH/FR/SA/SU
快速获取下周一、上周五、当月第N个星期二,用于排班、账单日、每周定时任务。MO(+1) = 下周一,FR(-1) = 上周五。
5. rrule 周期生成器
生成重复日期序列,替代手动循环判断:
- DAILY 每日、WEEKLY 每周、MONTHLY 每月、YEARLY 每年;
- count=5 生成5条,until=截止日期;
- byweekday 指定星期、bymonthday 指定每月几号。
6. 两个日期精确差值计算
timedelta 只能算出总天数,无法区分几年几个月;relativedelta(结束时间, 起始时间) 直接拆分年、月、日差值,做年龄、服务时长统计。
7. 工作日筛选
结合 rrule + 星期枚举,一键筛选当月所有工作日,排除周六周日,薪资、考勤报表必备。
8. 时区转换 tzutc / tzoffset
内置UTC时区,支持自定义任意时区偏移(东八区UTC+8),解决跨时区日志、海外接口时间转换。
9. 季度计算
自动算出当前季度起始、结束日期,季度报表、季度数据统计。
10. fuzzy 模糊提取
网页混杂文字里自动捞出日期数字,爬虫不用正则提取时间字符串。
核心对比(datetime vs dateutil)
| 功能 | 原生datetime | python-dateutil |
|---|---|---|
| 自动解析任意日期字符串 | ❌ 必须指定格式 | ✅ parser.parse |
| 加减月份/年份 | ❌ 大小月报错 | ✅ relativedelta |
| 按星期跳转(下周一) | ❌ 大量判断 | ✅ MO(+1) |
| 生成周期重复日期 | ❌ 手写循环 | ✅ rrule |
| 年月拆分时间间隔 | ❌ 仅总天数 | ✅ relativedelta(结束,起始) |
| 模糊提取文本中的日期 | ❌ 正则硬写 | ✅ fuzzy=True |
| 批量筛选工作日 | ❌ 循环判断 | ✅ rrule+weekday |
运行命令
# 安装
pip install python-dateutil
# 执行代码
python dateutil_demo.py
典型业务使用场景总结
- 爬虫:fuzzy模糊解析网页杂乱发布时间;
- 后台统计:近7天、上月、本季度数据时间范围生成;
- 定时任务:rrule生成每周/每月执行时间;
- 考勤薪资:筛选当月工作日;
- 报表导出:自动获取每月、季度起止日期;
- 用户时长:计算注册到现在几年几个月;
- 多时区系统:UTC与本地时间互相转换;
- 账单提醒:每月1号、每周一自动生成提醒日期。
更多推荐



所有评论(0)