将 data_orders 表的三个 timestamp 字段(created_at、updated_at、processed_at)以及其他相关表的时间字段,从使用 UTC 时间改为使用东八区(Asia/Shanghai)时间。
文件: app/core/common/timezone_utils.py
创建了统一的时区处理工具模块,提供以下功能:
now_china(): 获取当前东八区时间(带时区信息)now_china_naive(): 获取当前东八区时间(不带时区信息,用于数据库存储)to_china_time(): 将任意时区的时间转换为东八区时间utc_to_china_naive(): 将 UTC 时间转换为东八区时间(不带时区信息)app/models/data_product.pyDataProduct 模型:
created_at: datetime.utcnow → now_china_naiveupdated_at: datetime.utcnow → now_china_naivemark_as_viewed(): 使用 now_china_naive()update_data_stats(): 使用 now_china_naive()DataOrder 模型:
created_at: datetime.utcnow → now_china_naiveupdated_at: datetime.utcnow → now_china_naiveprocessed_at: 默认值保持 None,但在更新时使用 now_china_naive()update_status(): 使用 now_china_naive()set_extraction_result(): 使用 now_china_naive()set_graph_analysis(): 使用 now_china_naive()set_result(): 使用 now_china_naive()reject(): 使用 now_china_naive()app/models/metadata_review.pyMetadataReviewRecord 模型:
created_at: datetime.utcnow → now_china_naiveupdated_at: datetime.utcnow → now_china_naiveMetadataVersionHistory 模型:
created_at: datetime.utcnow → now_china_naiveupdate_review_record_resolution 函数:
resolved_at: 使用 now_china_naive()updated_at: 使用 now_china_naive()app/core/data_service/data_product_service.py修正了所有使用 datetime.utcnow() 的地方:
register_product(): 更新现有产品和创建新产品时使用 now_china_naive()update_product_stats(): 使用 now_china_naive()refresh_product_stats(): 使用 now_china_naive()update_order(): 使用 now_china_naive()app/core/meta_data/redundancy_check.py修正了创建审核记录时的时间字段:
created_at: 使用 now_china_naive()updated_at: 使用 now_china_naive()app/core/business_domain/business_domain.py修正了创建审核记录时的时间字段:
created_at: 使用 now_china_naive()updated_at: 使用 now_china_naive()本次修正使用了 zoneinfo 模块,而不是第三方库 pytz。理由如下:
zoneinfo,Python 3.8 使用 backports.zoneinfopytz,zoneinfo 的 API 更符合 Python 的 datetime 使用习惯代码已兼容 Python 3.8 和 3.9+:
try:
# Python 3.9+
from zoneinfo import ZoneInfo
except ImportError:
# Python 3.8 使用 backports
from backports.zoneinfo import ZoneInfo
依赖要求:
backports.zoneinfo 包tzdata 包采用 naive datetime 存储策略:
这种策略的优点:
created_at, updated_at, processed_atcreated_at, updated_at, last_updated_at, last_viewed_atcreated_at, updated_at, resolved_atcreated_at所有依赖这些时间字段的业务逻辑都将使用东八区时间,包括:
数据库中已存在的记录可能使用的是 UTC 时间。建议:
-- 将 UTC 时间转换为东八区时间(+8小时)
UPDATE data_orders
SET created_at = created_at + INTERVAL '8 hours',
updated_at = updated_at + INTERVAL '8 hours',
processed_at = processed_at + INTERVAL '8 hours'
WHERE created_at < '2026-01-12 00:00:00'; -- 修正前的数据
UPDATE data_products
SET created_at = created_at + INTERVAL '8 hours',
updated_at = updated_at + INTERVAL '8 hours',
last_updated_at = last_updated_at + INTERVAL '8 hours',
last_viewed_at = last_viewed_at + INTERVAL '8 hours'
WHERE created_at < '2026-01-12 00:00:00';
UPDATE metadata_review_records
SET created_at = created_at + INTERVAL '8 hours',
updated_at = updated_at + INTERVAL '8 hours',
resolved_at = resolved_at + INTERVAL '8 hours'
WHERE created_at < '2026-01-12 00:00:00';
UPDATE metadata_version_history
SET created_at = created_at + INTERVAL '8 hours'
WHERE created_at < '2026-01-12 00:00:00';
所有 API 返回的时间字段(ISO 8601 格式)现在表示的是东八区时间,而不是 UTC 时间。
created_at 字段是否为东八区当前时间updated_at 和 processed_at 是否正确last_viewed_at 是否更新为东八区时间本次修正符合 BUSINESS_RULES.md 中的规定:
# Use East Asia timezone for all timestamps
from datetime import datetime
import pytz
虽然业务规则中提到了 pytz,但我们使用了更现代的 zoneinfo 标准库,功能等价且更优。
✅ 所有相关的时间字段已统一使用东八区时间
✅ 创建了统一的时区工具模块,便于后续维护
✅ 修正了 6 个文件,涉及模型层和服务层
✅ 代码通过了 linter 检查,无语法错误
✅ 符合项目的业务规则要求
修正日期: 2026-01-12
修正人: AI Assistant