频道 9 万条评论导进本地库,我被时区字段坑了整晚
手上这个频道后台导出的评论 CSV,是 2024-11 那版后台的格式,9 万多行,字段里有 create_time 和 update_time,长这样:2024-11-03T14:22:07Z。我第一反应是直接 INSERT 进 SQLite,按字符串排序看时间线,白天跑起来一切正常,晚上把一周的日增评论拉出来对,发现每天的数据都往前偏了 8 小时——凌晨 0 点到 8 点发的评论全被算进了前一天。
原因不复杂:CSV 里是 UTC,我人在东八区,看后台页面时是本地时间,两边混着对,脑子里默认它们是一回事。修复分两步,先把入库时的时间统一成 UTC 的整数秒,别留字符串:
CREATE TABLE comments (
id TEXT PRIMARY KEY,
video_id TEXT NOT NULL,
created_utc INTEGER NOT NULL,
updated_utc INTEGER
);
导入时用 Python 转一次,别在 SQL 里硬转:
from datetime import datetime, timezone
ts = datetime.strptime(row["create_time"], "%Y-%m-%dT%H:%M:%SZ")
created = int(ts.replace(tzinfo=timezone.utc).timestamp())
查日增的时候显式加偏移,不要靠本地时区:
SELECT date(created_utc, 'unixepoch', '+8 hours') AS d, count(*)
FROM comments GROUP BY d ORDER BY d;
这样做的代价是:所有查询都得记住带上 '+8 hours',忘一次就错一次。我后来在视图里封了一层,建了个 comments_local 视图固定加 8 小时,日常查询只读视图,导出原始数据时才碰底表。另一个取舍是存整数秒而不是 ISO 字符串,可读性差一点,但排序、分桶、跨表 join 都不会因为格式不一致翻车。
会失效的地方也踩过:一是有些后台导出字段是空的,strptime 直接抛异常,得先判空再转,否则整批导入中断;二是有少量行带毫秒,%SZ 匹配不上,得用 fromisoformat 兜底;三是如果哪天后台改成带时区偏移的格式(比如 +08:00),固定 +8 hours 的视图就会多算一次,得改成先归一化到 UTC 再展示。我现在导入前会先抽样 100 行看格式,不假设它永远不变。
你们导后台评论时,是存 UTC 整数还是存带偏移的字符串?我这边因为还要按周做同比,暂时没找到比整数秒更省事的选择。
0
赞同度 100% · 0 条评论 · 5 阅读
0 条评论
还没有评论,写下第一条。