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

使用datetime作为JSON存储计时器时数值异常问题求助

问题分析与修复方案

我帮你排查了代码里的几个关键问题,这就是为什么你的flytimer总是被重置为0,而且时间判断逻辑异常的原因:

1. 全局currenttime只计算一次

你把currenttime定义在全局作用域里,这意味着机器人启动时它会计算一次当前时间,之后就一直用这个旧值,不会随着时间更新。这样每次触发!flight命令时,时间差的计算完全错误,甚至会让你误以为flytimer被莫名重置了。

修复:把currenttime的计算移到!flight命令的处理逻辑里,每次触发命令时重新获取当前时间。

2. 错误的条件判断if get_flytimer is None:

这里你是在判断函数对象get_flytimer是否为None,而不是判断用户的flytimer值是否为空或未设置。这个条件永远为False,所以每次都会进入else分支,逻辑完全走偏。

修复:应该调用get_flytimer(message.author)获取用户的实际flytimer值,再进行判断。其实可以简化逻辑,不管用户是不是第一次使用,直接计算时间差,只要满足条件(第一次使用或时间差≥120秒)就允许执行命令。

3. 冗余的函数参数导致混淆

add_flytimer函数定义里的flytimer参数根本没被使用,你在函数里直接赋值为当前时间的秒数,这个多余的参数容易让你误解代码逻辑,建议去掉。

4. 剩余时间计算错误

你原来的代码里把已过去的时间takeflight当作剩余时间返回给用户,这会导致提示信息错误。正确的剩余时间应该是120 - takeflight。


修复后的完整代码片段

import datetime
import json
import discord

try:
    with open("timer.json") as fp:
        timer = json.load(fp)
except Exception:
    timer = {}

def save_timer():
    with open("timer.json", "w") as fp:  # 用"w"模式足够,覆盖写入即可
        json.dump(timer, fp, sort_keys=True, indent=4)

# 去掉冗余的flytimer参数,直接在函数内计算时间戳
def add_flytimer(user: discord.User):
    user_id = user.id
    if user_id not in timer:
        timer[user_id] = {}
    current_timestamp = (datetime.datetime.utcnow() - datetime.datetime.utcfromtimestamp(0)).total_seconds()
    timer[user_id]["flytimer"] = current_timestamp
    save_timer()

def get_flytimer(user: discord.User):
    user_id = user.id
    if user_id in timer:
        return timer[user_id].get("flytimer", 0)
    return 0

def reset_flytimer(user: discord.User):
    user_id = user.id
    if user_id in timer:
        timer[user_id]["flytimer"] = 0
        print("{} flight timer reset".format(user.name))
        save_timer()

# 命令处理逻辑(根据你的Discord.py版本调整发送消息的方法)
@client.event
async def on_message(message):
    if message.content.startswith('!flight'):
        # 每次触发命令时重新计算当前时间戳
        currenttime = (datetime.datetime.utcnow() - datetime.datetime.utcfromtimestamp(0)).total_seconds()
        user_flytimer = get_flytimer(message.author)
        takeflight = currenttime - user_flytimer
        
        # 第一次使用(flytimer为0)或者时间差≥120秒,允许执行
        if takeflight >= 120 or user_flytimer == 0:
            add_flytimer(message.author)
            print(f"Current time: {currenttime}, User flytimer: {get_flytimer(message.author)}")
            # 新版Discord.py用message.channel.send,旧版用send_message,根据你的版本调整
            await message.channel.send(f"{message.author} takes a flight to NY")
        else:
            remaining_seconds = 120 - takeflight
            await message.channel.send(f"{message.author} you still have {int(remaining_seconds)} seconds until the next flight")

额外说明

  • 我把变量名id改成了user_id,避免和Python内置的id()函数冲突,这是个编码好习惯。
  • 如果你的Discord.py版本是v1.0+,send_message已经被弃用,改用message.channel.send,代码里已经标注了这一点。
  • 现在每次触发!flight命令时,都会正确更新用户的flytimer到当前时间戳,JSON文件里的数值也会正常保存,不会再被错误重置为0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:30:48