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

如何将time.time()结果转换为小时和分钟并写入数据库?

解决Discord机器人语音时长计算与格式化写入数据库问题

你的代码存在一个关键问题:t1 是函数内的局部变量,用户进入语音频道后函数执行完毕,t1 的值会被销毁,等用户退出语音时 t1 又会被重新初始化为0,导致无法正确计算实际语音时长。需要把用户的语音开始时间存储在跨事件可保留的位置,比如Cog类的属性中。

同时,将秒数转换为小时+分钟格式可通过对总秒数做整除、取余运算实现。下面是修正后的完整代码:

import time
from discord.ext import commands

class VoiceTracker(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        # 用字典存储用户语音开始时间,键为 (成员ID, 服务器ID),避免不同服务器的同一用户数据冲突
        self.voice_start_times = {}

    @commands.Cog.listener()
    async def on_voice_state_update(self, member, before, after):
        async with self.bot.db.cursor() as cursor:
            # 获取用户当前累计语音时长记录
            await cursor.execute("SELECT voicetime FROM users WHERE member_id = ? AND guild_id = ?", 
                                (member.id, member.guild.id))
            voicetime_record = await cursor.fetchone()
            current_total = voicetime_record[0] if voicetime_record else 0

            # 用户从无频道进入有频道(加入语音)
            if before.channel is None and after.channel is not None:
                self.voice_start_times[(member.id, member.guild.id)] = time.time()
            
            # 用户从有频道退出到无频道(离开语音)
            elif before.channel is not None and after.channel is None:
                # 取出对应开始时间,不存在则跳过计算
                start_time = self.voice_start_times.pop((member.id, member.guild.id), None)
                if not start_time:
                    return
                
                # 计算本次语音总秒数
                total_seconds = time.time() - start_time
                # 转换为小时+分钟格式
                hours = int(total_seconds // 3600)
                minutes = int((total_seconds % 3600) // 60)
                formatted_duration = f"{hours}小时{minutes}分钟"
                
                # 写入数据库(两种存储方式二选一)
                # 方式1:存储格式化后的字符串(需确保voicetime字段为TEXT类型)
                await cursor.execute("UPDATE users SET voicetime = ? WHERE member_id = ? AND guild_id = ?",
                                    (formatted_duration, member.id, member.guild.id))
                # 方式2:推荐存储总秒数(字段为INT/FLOAT),后续显示时再格式化,便于数值运算
                # await cursor.execute("UPDATE users SET voicetime = voicetime + ? WHERE member_id = ? AND guild_id = ?",
                #                     (total_seconds, member.id, member.guild.id))
            
            await self.bot.db.commit()

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

核心说明:

  • 新增self.voice_start_times字典存储用户语音起始时间,用(成员ID, 服务器ID)作为键,避免跨服务器的用户数据混乱。
  • 时长转换逻辑:总秒数整除3600得到小时数,剩余秒数整除60得到分钟数。
  • 数据库存储建议:优先选择存储总秒数,数值类型更便于后续的累加、排序、统计等操作,需要展示时再转换为小时分钟格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:15:13