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

如何修复Discord天气Bot中的时间偏移问题?

问题

我用下面的Discord Bot代码调用OpenWeatherMap API获取未来24小时天气,代码能正常运行返回结果,但返回的时间比对应温度的实际时间超前6小时(把示例输出里的时间回调6小时后,温度才符合实际情况),该怎么修复?

import requests
import discord

def get_weather(city, state, api_key):
    base_url = "http://api.openweathermap.org/data/2.5/forecast"
    params = {
        "q": f"{city},{state}",
        "appid": api_key,
        "units": "imperial",
        "cnt": 9
    }

    response = requests.get(base_url, params=params)
    data = response.json()

    # Check if the API request was successful
    if response.status_code == 200:
        # Extract and format the weather information
        weather_info = []
        for forecast in data['list']:
            date_time = forecast['dt_txt']
            temperature = forecast['main']['temp']
            weather_description = forecast['weather'][0]['description']
            weather_info.append(f"{date_time}: {temperature}°F, {weather_description}")

        return weather_info
    else:
        return f"Error: {data['message']}"

api_key = ''
bot_token = ''
intents = discord.Intents.default()
intents.message_content = True

client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f"We have logged in as {client.user}")

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content.startswith("!weather"):
        await message.channel.send("Enter the state: ")

        def check_state(m):
            return m.author == message.author and m.channel == message.channel

        state_msg = await client.wait_for("message", check=check_state, timeout=60)
        state = state_msg.content

        await message.channel.send("Enter the city: ")

        def check_city(m):
            return m.author == message.author and m.channel == message.channel

        city_msg = await client.wait_for("message", check=check_city, timeout=60)
        city = city_msg.content

        weather_info = get_weather(city, state, api_key)

        if isinstance(weather_info, str):
            await message.channel.send(weather_info)
        else:
            await message.channel.send("\n".join(weather_info))

client.run(bot_token)

返回结果示例:

2023-07-05 00:00:00: 81.46°F, light rain
2023-07-05 03:00:00: 77.63°F, few clouds
2023-07-05 06:00:00: 72.77°F, clear sky
2023-07-05 09:00:00: 70.63°F, clear sky
2023-07-05 12:00:00: 76.95°F, clear sky
2023-07-05 15:00:00: 87.58°F, clear sky
2023-07-05 18:00:00: 93.49°F, few clouds
2023-07-05 21:00:00: 92.32°F, broken clouds
2023-07-06 00:00:00: 82.67°F, broken clouds
解决方案

问题根源是OpenWeatherMap返回的dt_txt字段是UTC标准时间,而你需要的是目标城市的本地时间。推荐以下两种修复方式:

方式一:利用API返回的时区偏移自动转换(最优解)

API返回的city字段中包含timezone值(单位为秒),代表目标城市与UTC的时间偏移量。我们可以用这个值将UTC时间转换为本地时间,适配所有时区的城市。

修改后的完整代码如下:

import requests
import discord
from datetime import datetime, timedelta  # 导入时间处理模块

def get_weather(city, state, api_key):
    base_url = "http://api.openweathermap.org/data/2.5/forecast"
    params = {
        "q": f"{city},{state}",
        "appid": api_key,
        "units": "imperial",
        "cnt": 9
    }

    response = requests.get(base_url, params=params)
    data = response.json()

    if response.status_code == 200:
        weather_info = []
        # 获取目标城市的时区偏移(秒)
        timezone_offset = data['city']['timezone']
        for forecast in data['list']:
            # 解析UTC时间字符串
            utc_time = datetime.strptime(forecast['dt_txt'], "%Y-%m-%d %H:%M:%S")
            # 转换为本地时间:UTC时间 + 时区偏移量
            local_time = utc_time + timedelta(seconds=timezone_offset)
            # 格式化本地时间为字符串
            local_time_str = local_time.strftime("%Y-%m-%d %H:%M:%S")
            
            temperature = forecast['main']['temp']
            weather_description = forecast['weather'][0]['description']
            weather_info.append(f"{local_time_str}: {temperature}°F, {weather_description}")

        return weather_info
    else:
        return f"Error: {data['message']}"

# 以下代码保持不变
api_key = ''
bot_token = ''
intents = discord.Intents.default()
intents.message_content = True

client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f"We have logged in as {client.user}")

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content.startswith("!weather"):
        await message.channel.send("Enter the state: ")

        def check_state(m):
            return m.author == message.author and m.channel == message.channel

        state_msg = await client.wait_for("message", check=check_state, timeout=60)
        state = state_msg.content

        await message.channel.send("Enter the city: ")

        def check_city(m):
            return m.author == message.author and m.channel == message.channel

        city_msg = await client.wait_for("message", check=check_city, timeout=60)
        city = city_msg.content

        weather_info = get_weather(city, state, api_key)

        if isinstance(weather_info, str):
            await message.channel.send(weather_info)
        else:
            await message.channel.send("\n".join(weather_info))

client.run(bot_token)

方式二:手动固定偏移(仅临时应急)

如果只是临时针对当前6小时的偏移场景,可以直接给UTC时间减去6小时,但这种方法不通用,换其他时区的城市就会失效:

# 在处理时间的部分替换为以下代码
utc_time = datetime.strptime(forecast['dt_txt'], "%Y-%m-%d %H:%M:%S")
local_time = utc_time - timedelta(hours=6)
local_time_str = local_time.strftime("%Y-%m-%d %H:%M:%S")

关键说明

  • 方式一通过API返回的timezone字段自动适配时区,是通用且正确的解决方案。
  • 必须导入datetime和timedelta模块来完成时间解析与转换操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 05:07:46