Skip to content

fix: resolve unhandled UTC timezone offset for timestamps in conversation records#5580

Merged
zouyonghe merged 3 commits intoAstrBotDevs:masterfrom
WintryWind7:fix/chat-time-utc
Mar 1, 2026
Merged

fix: resolve unhandled UTC timezone offset for timestamps in conversation records#5580
zouyonghe merged 3 commits intoAstrBotDevs:masterfrom
WintryWind7:fix/chat-time-utc

Conversation

@WintryWind7
Copy link
Contributor

@WintryWind7 WintryWind7 commented Feb 28, 2026

…tion records

在windows桌面端-更多功能-对话数据板块内,创建时间与更新时间显示与实际时间不符,经排查发现是SQLite 数据库不支持存储带时区的日期,取出的datetime对象是丢失了 UTC 标识的 naive datetime。此时在后端直接对其进行 JSON 序列化(转为字符串)或调用 .timestamp() / .astimezone() 时,Python 解释器会将其视作操作系统的“本地时区”强行发生偏移,导致正确原本存入的 UTC 时间被二次破坏。

Modifications / 改动点

修复了由于后端输出 Naive Datetime 导致前端页面时间解析发生时差偏移的问题,仅涉及少量序列化拦截与格式替换:

  • astrbot/dashboard/server.py: 自定义 AstrBotJSONProvider,在全局 JSON 序列化时拦截 datetime 对象,强制补充 UTC 零时区标识(+00:00)。
  • astrbot/core/conversation_mgr.py: 将 datetime.timestamp() 运算改为 replace(tzinfo=timezone.utc).timestamp(),避免被本地环境带偏时区计算秒数。
  • astrbot/dashboard/routes/chat.py
    astrbot/dashboard/routes/chatui_project.py
    astrbot/dashboard/routes/live_chat.py
    astrbot/dashboard/routes/open_api.py
    (以上 4 个

文件):移除多余的原生 astimezone() 调用,全部统一为 replace(tzinfo=timezone.utc).isoformat() 输出绝对 UTC 字符串,交由无感的前端浏览器接管并呈现安全的本地时区渲染。

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

949f4770-40d0-4fff-8327-8b96a0bd037a 9b71274f-4399-40e3-b179-2da5c8c82421 ---

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

由 Sourcery 提供的摘要

确保所有仪表盘和会话相关的时间戳都作为带有 UTC 信息的时间值进行处理和序列化,以避免时区偏移问题。

错误修复:

  • 修正仪表盘、聊天、实时聊天和 OpenAPI 响应中 created_atupdated_at 时间戳不正确的问题,该问题由“天真(naive)”的 datetime 被解释为本地时区导致。

改进内容:

  • 引入共享的 datetime 工具,用于将“天真(naive)”的 datetime 规范化为 UTC,并将其转换为 ISO 8601 字符串或 Unix 时间戳。
  • 将仪表盘的 Flask 应用配置为使用自定义 JSON provider,使其在序列化 datetime 对象时使用明确的 UTC ISO 8601 字符串。
  • 在会话管理和仪表盘路由中统一时间戳的生成方式,始终使用基于 UTC 的辅助方法。
Original summary in English

Summary by Sourcery

Ensure all dashboard and conversation timestamps are handled and serialized as UTC-aware values to avoid timezone offset issues.

Bug Fixes:

  • Correct incorrect created_at and updated_at timestamps in dashboard, chat, live chat, and OpenAPI responses caused by naive datetimes being interpreted in the local timezone.

Enhancements:

  • Introduce shared datetime utilities to normalize naive datetimes as UTC and convert them to ISO 8601 strings or Unix timestamps.
  • Configure the dashboard Flask app to use a custom JSON provider that serializes datetime objects as explicit UTC ISO 8601 strings.
  • Standardize timestamp generation across conversation management and dashboard routes to consistently use the UTC-based helpers.

Bug 修复:

  • 修复仪表盘和聊天界面中 created_atupdated_at 时间显示不正确的问题。该问题是由于“naive” datetime 被解释为本地时区时间而非 UTC 所导致。

增强内容:

  • 引入自定义 JSON 提供器,在 tzinfo 缺失时,将 datetime 对象序列化为带有显式 UTC 偏移量的 ISO 8601 字符串。
  • 统一会话管理和仪表盘路由中的时间戳生成与序列化逻辑,在计算 Unix 时间戳或 ISO 字符串之前,始终将存储的 datetime 视为 UTC。
Original summary in English

由 Sourcery 提供的摘要

确保所有仪表盘和会话相关的时间戳都作为带有 UTC 信息的时间值进行处理和序列化,以避免时区偏移问题。

错误修复:

  • 修正仪表盘、聊天、实时聊天和 OpenAPI 响应中 created_atupdated_at 时间戳不正确的问题,该问题由“天真(naive)”的 datetime 被解释为本地时区导致。

改进内容:

  • 引入共享的 datetime 工具,用于将“天真(naive)”的 datetime 规范化为 UTC,并将其转换为 ISO 8601 字符串或 Unix 时间戳。
  • 将仪表盘的 Flask 应用配置为使用自定义 JSON provider,使其在序列化 datetime 对象时使用明确的 UTC ISO 8601 字符串。
  • 在会话管理和仪表盘路由中统一时间戳的生成方式,始终使用基于 UTC 的辅助方法。
Original summary in English

Summary by Sourcery

Ensure all dashboard and conversation timestamps are handled and serialized as UTC-aware values to avoid timezone offset issues.

Bug Fixes:

  • Correct incorrect created_at and updated_at timestamps in dashboard, chat, live chat, and OpenAPI responses caused by naive datetimes being interpreted in the local timezone.

Enhancements:

  • Introduce shared datetime utilities to normalize naive datetimes as UTC and convert them to ISO 8601 strings or Unix timestamps.
  • Configure the dashboard Flask app to use a custom JSON provider that serializes datetime objects as explicit UTC ISO 8601 strings.
  • Standardize timestamp generation across conversation management and dashboard routes to consistently use the UTC-based helpers.

@auto-assign auto-assign bot requested review from Fridemn and Soulter February 28, 2026 17:23
@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Feb 28, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在解决后端处理日期时间对象时存在的时区偏移问题,该问题导致前端界面显示的时间与实际不符。通过在数据序列化和时间戳转换的关键环节强制使用 UTC 时区信息,确保了日期时间数据在整个系统中的一致性和准确性,从而为用户提供了正确的创建和更新时间显示。

Highlights

  • 时区偏移问题修复: 修复了桌面端对话数据中创建和更新时间显示不准确的问题,该问题源于 SQLite 数据库存储的日期时间对象在后端被错误地解释为本地时区。
  • 全局 JSON 序列化处理: 在全局 JSON 序列化过程中,通过自定义 AstrBotJSONProvider 拦截 datetime 对象,强制为其补充 UTC 零时区标识(+00:00),确保时间戳的正确性。
  • 时间戳计算标准化: 将 datetime.timestamp() 运算替换为 replace(tzinfo=timezone.utc).timestamp(),以避免因本地环境设置导致的时区偏移。
  • 前端日期时间渲染统一: 统一了多个路由文件中的日期时间输出格式,移除多余的 astimezone() 调用,改为使用 replace(tzinfo=timezone.utc).isoformat() 输出绝对 UTC 字符串,将本地时区渲染任务交由前端浏览器处理。
Changelog
  • astrbot/core/conversation_mgr.py
    • 修改了 created_at 和 updated_at 的时间戳计算方式,确保在转换为整数时间戳时明确指定 UTC 时区。
  • astrbot/dashboard/routes/chat.py
    • 更新了消息保存和会话获取逻辑中 created_at 和 updated_at 的序列化,将 astimezone().isoformat() 替换为 replace(tzinfo=timezone.utc).isoformat()。
  • astrbot/dashboard/routes/chatui_project.py
    • 在项目创建、列表和获取以及项目会话获取中,统一了 created_at 和 updated_at 的序列化方式,使用 replace(tzinfo=timezone.utc).isoformat()。
  • astrbot/dashboard/routes/live_chat.py
    • 修改了实时聊天消息保存时 created_at 的序列化,确保其以 UTC 格式输出。
  • astrbot/dashboard/routes/open_api.py
    • 在开放 API 的消息发送和会话获取中,调整了 created_at 和 updated_at 的序列化,使其输出为 UTC 格式。
  • astrbot/dashboard/server.py
    • 引入了自定义的 AstrBotJSONProvider,用于全局拦截 datetime 对象,并在其没有时区信息时默认添加 UTC 时区标识,然后进行 ISO 格式化。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我在这里给了一些总体反馈:

  • 在多个路由中重复出现的 obj.replace(tzinfo=timezone.utc).isoformat() 逻辑,说明可以考虑引入一个小的共享 helper(例如 to_utc_iso(dt)),把“naive→UTC”的转换集中到一个地方,确保行为一致。
  • conversation_mgr._convert_conv_from_v2_to_v1AstrBotJSONProvider 中,建议将 from datetime import timezone(以及 datetime)的导入移到模块级,而不是在函数/类内部导入,以保持导入方式一致并避免重复工作。
给 AI Agent 的提示词
Please address the comments from this code review:

## Overall Comments
- The repeated `obj.replace(tzinfo=timezone.utc).isoformat()` logic across multiple routes suggests introducing a small shared helper (e.g., `to_utc_iso(dt)`) to centralize the naive→UTC conversion and keep behavior consistent in one place.
- In `conversation_mgr._convert_conv_from_v2_to_v1` and `AstrBotJSONProvider`, consider moving `from datetime import timezone` (and `datetime`) imports to the module level instead of doing them inside functions/classes to keep imports consistent and avoid repeated work.

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈来改进以后的代码审查。
Original comment in English

Hey - I've left some high level feedback:

  • The repeated obj.replace(tzinfo=timezone.utc).isoformat() logic across multiple routes suggests introducing a small shared helper (e.g., to_utc_iso(dt)) to centralize the naive→UTC conversion and keep behavior consistent in one place.
  • In conversation_mgr._convert_conv_from_v2_to_v1 and AstrBotJSONProvider, consider moving from datetime import timezone (and datetime) imports to the module level instead of doing them inside functions/classes to keep imports consistent and avoid repeated work.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The repeated `obj.replace(tzinfo=timezone.utc).isoformat()` logic across multiple routes suggests introducing a small shared helper (e.g., `to_utc_iso(dt)`) to centralize the naive→UTC conversion and keep behavior consistent in one place.
- In `conversation_mgr._convert_conv_from_v2_to_v1` and `AstrBotJSONProvider`, consider moving `from datetime import timezone` (and `datetime`) imports to the module level instead of doing them inside functions/classes to keep imports consistent and avoid repeated work.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@dosubot
Copy link

dosubot bot commented Feb 28, 2026

Related Documentation

Checked 1 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

@dosubot dosubot bot added area:core The bug / feature is about astrbot's core, backend area:webui The bug / feature is about webui(dashboard) of astrbot. labels Feb 28, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This PR effectively addresses and resolves the timestamp offset issue caused by the loss of timezone information when reading naive datetimes from SQLite. The approach of explicitly handling UTC timezone is correct. However, the implementation contains several critical issues, such as missing module imports leading to NameError, and opportunities for improving code style and maintainability. Please refer to the specific review comments for details.

@zouyonghe
Copy link
Member

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我已经审查了你的更改,看起来非常不错!


Sourcery 对开源项目是免费的——如果你喜欢我们的审查,请考虑分享它们 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进之后的审查。
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@zouyonghe zouyonghe merged commit fd223bb into AstrBotDevs:master Mar 1, 2026
6 checks passed
astrbot-doc-agent bot pushed a commit to AstrBotDevs/AstrBot-docs that referenced this pull request Mar 1, 2026
@astrbot-doc-agent
Copy link

Generated docs update PR (pending manual review):
AstrBotDevs/AstrBot-docs#156
Trigger: PR merged


AI change summary:

  • zh/faq.md「管理面板相关」章节新增 FAQ「管理面板中对话记录的时间显示不正确」
  • en/faq.md「Dashboard Related」章节新增对应英文 FAQ 条目
  • 说明管理面板对话数据时间显示偏差问题,建议升级至最新版本修复
  • i18n 状态:中英文文档均已同步更新

Experimental bot notice:

  • This output is generated by AstrBot-Doc-Agent for review only.
  • It does not represent the final documentation form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend area:webui The bug / feature is about webui(dashboard) of astrbot. size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants