报错内容:
D:\work\envPy\lib\site-packages\apscheduler\util.py:95:
PytzUsageWarning: The zone attribute is specific to pytz's interface;
please migrate to a new time zone provider.
For more details on how to do so,
see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
if obj.zone == 'local':
D:\work\envPy\lib\site-packages\apscheduler\util.py:166:
PytzUsageWarning: The localize method is no longer necessary,
as this time zone supports the fold attribute (PEP 495).
For more details on migrating to a PEP 495-compliant implementation,
see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
return tz.localize(datetime_, is_dst=None)
D:\work\envPy\lib\site-packages\apscheduler\triggers\interval.py:66:
PytzUsageWarning: The normalize method is no longer necessary,
as this time zone supports the fold attribute (PEP 495).
For more details on migrating to a PEP 495-compliant implementation,
see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
return self.timezone.normalize(next_fire_time)
报错的代码:
import sys
from apscheduler.events import EVENT_JOB_ERROR
from apscheduler.events import EVENT_JOB_EXECUTED
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
import logging
logging.basicConfig(level=logging.INFO,
format='[%(asctime)s] %(filename)s -> %(funcName)s line:%(lineno)d [%(levelname)s]: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
stream=sys.stdout
)
# 循环任务
def loop_function(x):
logging.info(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + x)
logging.info(datetime.datetime.now(tz=pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S') + x)
# logging.info(datetime.datetime.now(tz=SH.strftime('%Y-%m-%d %H:%M:%S') + x))
# 一次性任务(会出错)
def once_function(x):
logging.info(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + x)
# 待捕获的异常
logging.error(1 / 0)
# 监听函数
def listener_function(event):
if event.exception:
logging.error('任务出错')
else:
logging.info('任务正常')
# 定时任务调用
scheduler = BlockingScheduler()
# scheduler = BlockingScheduler(timezone='Asia/Shanghai')
scheduler.add_job(func=once_function,
args=('一次性含有异常的任务',),
next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=5),
#next_run_time=(datetime.datetime.now() + datetime.timedelta(seconds=5)).astimezone(),
id='once_task',
#timezone='Asia/Shanghai'
)
scheduler.add_job(func=loop_function,
args=('循环任务',),
trigger='interval',
seconds=3,
#timezone='Asia/Shanghai',
id='loop_task')
# 添加监听器
scheduler.add_listener(callback=listener_function, mask=(EVENT_JOB_EXECUTED |
EVENT_JOB_ERROR))
# 设置日志
scheduler._logger = logging
# 开启定时任务
scheduler.start()
解决方法:
- 创建定时任务对象时,指定时区
scheduler=BlockingScheduler(timezone='Asia/Shanghai')
- 或者在添加定时任务时,指定时区。如果含有具体时间的参数时,需要根据时区对时间进行转换即增加
.astimezone()
:scheduler.add_job(func=once_function, args=('一次性含有异常的任务',), next_run_time=(datetime.datetime.now() + datetime.timedelta(seconds=5)).astimezone(), id='once_task', timezone='Asia/Shanghai' ) scheduler.add_job(func=loop_function, args=('循环任务',), trigger='interval', seconds=3, timezone='Asia/Shanghai', id='loop_task')
补充说明:
错误提示中的链接 https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html内容提及的zoneinfo库,在 python3.9 中才出现,是基于datetime、time模块的类型zoneinfo类而设计的。在 python3.9 之前使用的都是datetime模块中timezone类。
可以选择的时区参考文件