discord.py如何让Bot任务循环与系统时间或时区同步执行
解决方案
实现思路
- 利用
discord.py的tasks.loop提供的before_loop钩子,在循环正式启动前计算当前时间到下一个整点的等待时长 - 等待到首个整点后执行第一次任务,后续由每小时1次的循环自动触发,自然对齐所有整点
- 支持切换为指定时区时间计算,无需依赖第三方定时工具
完整修改后代码
import discord import asyncio import datetime # 如需使用指定时区,Python3.9+可导入zoneinfo # from zoneinfo import ZoneInfo from discord.ext import commands,tasks # 提前定义嵌入消息颜色,按需修改色值 system_color = 0xED4245 client = commands.Bot(command_prefix = '!', help_command=None) @client.event async def on_ready(): await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.listening, name='!help')) bot_test_clear.start() print(f"{client.user} is online") # 新增前置等待逻辑,循环启动前自动对齐下一个整点 @bot_test_clear.before_loop async def wait_for_next_hour(): # 使用系统本地时间计算 now = datetime.datetime.now() # 如需指定时区(如东八区),注释上一行、启用下一行即可 # now = datetime.datetime.now(ZoneInfo("Asia/Shanghai")) # 计算下一个整点的时间 next_hour = now.replace(minute=0, second=0, microsecond=0) + datetime.timedelta(hours=1) # 计算需要等待的秒数 wait_seconds = (next_hour - now).total_seconds() await asyncio.sleep(wait_seconds) @tasks.loop(hours=1) async def bot_test_clear(): # 替换为实际的频道数字ID,去掉字符串引号 channel_bot_test = client.get_channel(1234567890) messages = await channel_bot_test.history(limit=123).flatten() if not messages: return else: embed = discord.Embed(description='It has been 1 hour, clearing chats...', color=system_color) await channel_bot_test.send(embed=embed) await asyncio.sleep(10) await channel_bot_test.purge(limit=None) client.run('你的机器人token')
改动说明
- 新增了
wait_for_next_hour前置等待函数,会在任务循环启动前自动等待到下一个整点 - 保留原每小时1次的循环配置,首次执行后后续所有执行时间都会自动对齐整点
- 重启脚本后会重新计算下一个整点等待时间,不会出现计时偏移的问题
注意事项
- 请将代码中
1234567890替换为实际的Discord频道数字ID system_color可按需修改为你需要的嵌入消息颜色十六进制值- 若使用指定时区功能,Python 3.9以下版本可安装第三方库
pytz替代标准库zoneinfo实现相同功能
内容的提问来源于stack exchange,提问作者Broken DEV
相关产品推荐
相关产品推荐

