You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何discord.utils.sleep_until在Discord机器人定时任务中无限休眠?

解决discord.py中tasks.loop的before_loop里sleep_until无限休眠问题

你在Cog中定义了每分钟整点执行的定时任务,通过before_loop计算下一分钟整点并调用discord.utils.sleep_until等待,但'sleep done'始终未打印,任务无法正常启动。

问题原因

datetime.datetime.now()获取的是本地时间,而discord.utils.sleep_until要求传入的是UTC时间——discord.py内部所有时间相关逻辑均基于UTC实现。如果你的本地时区和UTC存在偏移,计算出的next_minute会和实际UTC时间不匹配,导致sleep_until进入无限等待状态。

解决方案

将时间计算切换为UTC时间,用datetime.datetime.utcnow()替代datetime.datetime.now(),修改后的代码如下:

import discord
from discord.ext import commands
from discord.ext import tasks
import datetime

class Fanfare(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.fanfare.start()

    @tasks.loop(seconds=60)
    async def fanfare(self):
        print('do something')

    @fanfare.before_loop
    async def fanfare_before_loop(self):
        await self.bot.wait_until_ready()

        # 计算下一分钟的整点时刻(使用UTC时间)
        now = datetime.datetime.utcnow()
        next_minute = now.replace(second=0, microsecond=0) + datetime.timedelta(minutes=1)

        # 调试打印
        print(now)
        print(next_minute)

        # 等待到下一分钟
        await discord.utils.sleep_until(next_minute)
        print('sleep done')

def setup(bot):
    bot.add_cog(Fanfare(bot))

补充说明

如果必须基于本地时间处理,也可以给时间对象添加时区信息,确保和discord.utils.sleep_until的要求一致。示例如下:

import pytz  # 需要先安装pytz库:pip install pytz

# 获取带时区的本地时间
local_tz = pytz.timezone('Asia/Shanghai')  # 替换为你的实际时区
now = datetime.datetime.now(local_tz)
next_minute = now.replace(second=0, microsecond=0) + datetime.timedelta(minutes=1)
# 转换为UTC时间后传入sleep_until
next_minute_utc = next_minute.astimezone(pytz.utc)
await discord.utils.sleep_until(next_minute_utc)

内容的提问来源于stack exchange,提问作者Mateo Vial

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:25:15