使用AsyncIOScheduler定时任务时遭遇PytzUsageWarning,如何迁移至PEP 495兼容的时区方案?
解决AsyncIOScheduler中的PytzUsageWarning问题
我明白你的困扰——那些时区相关的警告看起来确实让人头大,尤其是链接里的说明太复杂。其实核心就是Python现在推荐用标准库的时区工具替代老旧的pytz,而APScheduler(AsyncIOScheduler是它的异步实现)只要稍作调整就能消除这些警告,我给你一步步讲清楚:
第一步:先确保APScheduler是新版本
APScheduler从3.10版本开始支持Python标准库的时区处理(也就是PEP 495提到的fold属性),所以先升级你的库:
pip install --upgrade apscheduler
第二步:替换时区处理方式
你之前的代码没指定时区,APScheduler默认会用pytz来获取本地时区,这就是警告的来源。现在我们改用Python3.9+自带的zoneinfo模块(如果是Python3.8及以下,先装backports.zoneinfo:pip install backports.zoneinfo)。
修改后的代码示例:
from apscheduler.schedulers.asyncio import AsyncIOScheduler # Python3.9+用下面这行,低版本换成 from backports.zoneinfo import ZoneInfo from zoneinfo import ZoneInfo def job(): # 这里写你的消息发送逻辑 print("定时消息已发送") if __name__ == "__main__": # 创建调度器时指定时区,比如你所在的Asia/Shanghai scheduler = AsyncIOScheduler(timezone=ZoneInfo("Asia/Shanghai")) # 添加定时任务,参数和之前一样 scheduler.add_job(job, "cron", day_of_week="mon-fri", hour=16) scheduler.start() # 保持asyncio事件循环运行(脚本里需要这部分,不然会直接退出) import asyncio try: asyncio.get_event_loop().run_forever() except KeyboardInterrupt: pass
为什么这样改能消除警告?
- 用
ZoneInfo创建的时区对象完全符合PEP 495的标准,不需要再用pytz的localize方法来处理时区 - 新版本的APScheduler会自动识别
ZoneInfo对象,不再依赖pytz的旧接口,自然就不会弹出那些警告了
如果你之前手动处理过时间(比如用pytz.localize)
如果你的代码里还有手动处理datetime的部分,也可以改成这样:
旧的pytz写法:
import pytz from datetime import datetime naive_dt = datetime(2024, 5, 20, 16, 0) # 给 naive datetime 添加时区信息 aware_dt = pytz.timezone("Asia/Shanghai").localize(naive_dt)
新的标准库写法:
from zoneinfo import ZoneInfo from datetime import datetime # 直接创建带时区的datetime aware_dt = datetime(2024, 5, 20, 16, 0, tzinfo=ZoneInfo("Asia/Shanghai")) # 如果是已有的naive datetime,转成带时区的 naive_dt = datetime(2024, 5, 20, 16, 0) aware_dt = naive_dt.astimezone(ZoneInfo("Asia/Shanghai"))
这样改完之后,那些烦人的警告应该就消失了,功能也和原来完全一样~
内容的提问来源于stack exchange,提问作者Sergo055
相关产品推荐
相关产品推荐

