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

如何在Discord机器人中用“days ago”格式显示用户日期?

解决Discord机器人中日期转“距今天数”的时区问题

问题核心

你在开发Discord机器人时,想要将用户的账号创建日期、服务器加入日期从格式化日期改为“距今天数”格式,但计算时间差时因时区不匹配报错——Discord返回的user.created_at和user.joined_at是带UTC时区的datetime对象,而你用的datetime.now()是本地无时区的,两者无法直接相减,即使移除时区感知也会导致计算偏差。

解决方案

统一使用UTC时区计算时间差(Discord的所有时间戳均基于UTC),封装一个辅助函数处理时间差转换,替换原代码中的日期显示逻辑即可。

辅助函数示例

from datetime import datetime, timezone

def get_time_ago(target_time):
    utc_now = datetime.now(timezone.utc)
    duration = utc_now - target_time

    total_seconds = int(duration.total_seconds())
    days, remainder = divmod(total_seconds, 86400)
    hours, remainder = divmod(remainder, 3600)
    minutes, seconds = divmod(remainder, 60)

    # 根据时间差大小自动选择显示单位
    if days > 0:
        return f"{days}天前"
    elif hours > 0:
        return f"{hours}小时前"
    elif minutes > 0:
        return f"{minutes}分钟前"
    else:
        return f"{seconds}秒前"

修改后的完整机器人代码

import discord
from datetime import datetime, timezone
from discord.ext import commands

intents = discord.Intents.all()
bot = commands.Bot(command_prefix='.', intents=intents)

def get_time_ago(target_time):
    utc_now = datetime.now(timezone.utc)
    duration = utc_now - target_time

    total_seconds = int(duration.total_seconds())
    days, remainder = divmod(total_seconds, 86400)
    hours, remainder = divmod(remainder, 3600)
    minutes, seconds = divmod(remainder, 60)

    if days > 0:
        return f"{days}天前"
    elif hours > 0:
        return f"{hours}小时前"
    elif minutes > 0:
        return f"{minutes}分钟前"
    else:
        return f"{seconds}秒前"

@bot.event
async def on_ready():
    print("Ready!")

@bot.command(name="user")
async def user(ctx, user: discord.Member=None):
    user = user or ctx.author

    # 简化角色列表生成逻辑
    rlist = [role.mention for role in user.roles if role.name != "@everyone"]
    b = ','.join(rlist) if rlist else "No roles"

    embed = discord.Embed(colour=user.color, timestamp=ctx.message.created_at)
    embed.set_author(name=f"User Info - {user}")
    embed.set_thumbnail(url=user.avatar.url)
    embed.set_footer(text=f'Requested by - {ctx.author}', icon_url=ctx.author.avatar.url)

    embed.add_field(name='ID:', value=user.id, inline=False)
    embed.add_field(name='Name:', value=user.display_name, inline=False)

    # 替换为时间差格式显示
    embed.add_field(name='Created at:', value=get_time_ago(user.created_at), inline=False)
    embed.add_field(name='Joined at:', value=get_time_ago(user.joined_at), inline=False)
    
    embed.add_field(name='Bot?', value=user.bot, inline=False)
    embed.add_field(name=f'Roles:({len(rlist)})', value=b, inline=False)
    embed.add_field(name='Top Role:', value=user.top_role.mention, inline=False)

    await ctx.send(embed=embed)

关键说明

  1. 时区统一:用datetime.now(timezone.utc)获取当前UTC时间,与Discord返回的UTC时区时间直接计算差值,彻底避免时区不匹配错误。
  2. 灵活显示:辅助函数会根据时间差自动选择最合理的显示单位,若只需固定显示天数,直接返回f"{days}天前"即可。
  3. 代码优化:用列表推导式简化角色列表生成逻辑,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:55:25