外观
多时区报表口径怎么定(事件时区 / 业务日切 / 存储 UTC)
难度与前置
难度:进阶
前置:表内有事件时间字段;知道报表按「业务日」出数,而不是随口按服务器本地时区。
读完能做什么:为多市场报表写清三时钟对齐规则(事件时区 / 业务日切 / 存储 UTC),并给出跨日边界可重复的验收思路,避免时区差异被当成丢数或口径漂移。
适用场景
- 同一套投放/内容报表服务多个国家或时区市场
- 存储统一 UTC,但业务要按当地自然日或活动日切看数
- 对账常在日界附近抖,需要区分「时区」与「真丢数」
- 夏令时(DST)切换日需要明确用哪套偏移
不适用:
真实场景(一条)
短剧投放同时跑「上海主站」与「美西活动」。仓内 event_ts 存 UTC,ADS 按 dt(上海日)汇总。美西运营按当地自然日核对渠道后台,日界前后消耗对不齐,群里骂「丢数」。
按本清单:
- 书面约定:存储 UTC;美西报表业务日切 =
America/Los_Angeles当地日;上海报表 =Asia/Shanghai - ADS 分市场主题或增加
biz_tz+biz_dt,禁止混用一个dt冒充两市场 - 跨日边界抽
event_id:UTC 日、上海日、美西日三列对照,差异可解释 - 对账分诊时「时区」枝优先于「口径」枝(见 recon-triage)
观察两周:日界误报工单从每周多次降到 0;无真实内部金额写进文档。
怎么做(步骤清单)
1. 先钉死三时钟(一张表写进口径文档)
| 时钟 | 含义 | 推荐约定 |
|---|---|---|
| 存储时间 | 表里落盘的时间戳 | UTC(或带 offset 的绝对时间);禁止「服务器本地」无文档 |
| 事件时区 | 事件发生地/设备/账户时区 | 能取则保留 event_tz;取不到则用市场默认时区并打标 |
| 业务日切 | 报表说的「一天」从何时到何时 | 按市场:biz_tz + biz_dt;活动可另定「活动日切」但必须单列 |
text
多时区口径卡(最小)
报表 / ADS:________
存储:UTC □ 其他(写明):________
市场列表:________
各市场 biz_tz:________
业务日切规则:当地 00:00–24:00 □ 活动定制:________
DST 策略:□按 IANA 时区规则 □固定 UTC 偏移(不推荐除非合规要求)
负责人:________ 版本:________对齐 指标口径一致性:时区规则变更 = 口径变更,走变更窗,不私自改 SQL。
2. 对齐规则(写入 / 汇总 / 对账)
- 写入:明细保留 UTC 时间戳;可选冗余
biz_dt(按目标市场算好),或下游按市场计算——二选一写清,禁止有的任务按上海、有的按 UTC 日切 - 汇总:
GROUP BY biz_dt, market(或等价);跨市场合计必须声明「先各市场当地日,再加总」还是「先统一到单一时区再加总」——两种结果不同,选一种并文档化 - 对账:与渠道后台比时,用对方的业务日切;源未按该日切封闭则先走延迟枝(freshness-sla、recon-triage)
- 平台:调度与仓储通用原则见 platform-principles,不绑单一厂商时区配置名
3. 跨日边界验收 SQL 思路(模板,非厂商方言)
目标:证明「同一批事件在不同日切下的归属可解释」,不是抄生产机密查询。
text
思路 A:同一 event_id 三列日切
选跨界窗口:UTC 日切换前后各 N 小时(及目标市场 DST 切换日)
对样例事件输出:
event_id
event_ts_utc
dt_utc = 按 UTC 截日
biz_dt_market_a = 按市场 A 时区截日
biz_dt_market_b = 按市场 B 时区截日
断言:
- 无 event_id 丢失
- 归属差异仅出现在日界附近,且与时区偏移方向一致
- 聚合后 market_a 的 biz_dt 合计 = 明细按规则汇总(容差内)text
思路 B:边界桶计数
对某市场 biz_dt = D:
统计 event_ts_utc 落入「当地 D 的 UTC 区间」的行数
与 ADS where biz_dt=D 行数比
期望:diff = 0 或仅延迟原因码text
思路 C:DST 日专项
在夏令时切换日重复 A/B;记录偏移从 ____ 变为 ____
禁止用固定 +8/+0 硬编码混充 IANA 规则(除非口径卡写死且合规允许)样例数据优先合成或脱敏夹具;跨日边界行要进 测试样例集 类清单(若该主题有 fixture)。
4. 出数与 SLA 注意点
- 「业务日 D 出数完成」的墙钟,按 出数责任时区(通常总部或主题 owner 时区)写进 SLA,同时注明市场当地日含义——避免美西同事以为「他的自然日 D」已封闭
- 新鲜度监控的分区键若是
biz_dt,延迟告警要按市场分别看,或文档说明单一dt代表哪套日切
常见坑(至少这些)
- 全链路按服务器本地时区截日,扩市场后静默漂移
- 存储已是 UTC,报表仍把 UTC 日当当地日
- 多市场共用一个
dt字段,对账永远在日界吵 - 用固定 +8 硬编码,DST 日炸
- 跨市场直接加总当地日指标,不声明口径
- 源未封闭就按当地日对账,误判丢数
- 改时区规则不走口径变更,看板环比假跌
- 文档写真实公司收入/ROI 数字当例子(禁止)
- 把本篇写成某云控制台时区设置截图课
如何验收(带数字的前后对比)
| 项 | 改前(示例) | 改后(目标) |
|---|---|---|
| 三时钟口径卡 | 无 | 每多市场报表 1 份,有版本号 |
| 日界对账误报(时区当丢数) | ≥ 1 次/周 | 观察期 0 |
| 跨日边界样例/SQL 思路可复跑 | 无 | 有;边界窗 diff 可解释 |
| DST 日专项 | 未测 | 切换日有记录或 N/A 声明 |
| 时区规则变更走口径变更单 | 否 | 是 |
| 文档含真实内部指标 | 有风险 | 0 |
text
多时区口径验收记录(可复制)
报表:________ 市场:________
存储:UTC Y/N biz_tz:________ 口径版本:________
边界窗:____~____(上海墙钟) 样例 event 数:____
三列日切对照:通过/失败 DST 日:测/跳过原因 ____
对账:按对方日切 Y/N 延迟已排除 Y/N diff:____
误报工单(观察 ____ 天):____
签字(口径 owner):________ 日期:________Checklist:
- [ ] 三时钟表完整,DST 策略明确
- [ ] 写入/汇总/对账对齐规则成文
- [ ] 跨日边界验收思路可复制(非机密生产 SQL)
- [ ] 链到 metric-consistency / recon-triage / freshness-sla / platform-principles
- [ ] 无真实公司指标;非厂商菜单课
相关专篇(互链,不重写)
| 你要做的事 | 看哪篇 |
|---|---|
| 口径立项与变更 | 指标口径一致性 |
| 对账失败是否时区枝 | 对账失败分诊 |
| 源封闭与出数时刻 | 新鲜度 SLA |
| 云上通用落地原则 | 云上数仓通用原则 |
| 对账容差与原因码 | 对账设计 |
| 本篇 | 只定多时区三时钟与边界验收,不替代上述专篇 |
相关面试题
题库小程序链接待定;先用站内锚点占位。
- [ ] 题:事件时区、业务日切、存储 UTC 三者如何分工?为何禁止「服务器本地」截日无文档?(考察点:三时钟口径卡)→ 占位:
#todo-interview-multi-tz-three-clocks - [ ] 题:跨日边界如何用同一
event_id证明归属差异来自时区而非丢数?(考察点:边界验收思路)→ 占位:#todo-interview-multi-tz-boundary - [ ] 题:多市场指标直接加总当地日,和先统一到单一时区再加总,为何必须二选一写进口径?(考察点:跨市场加总声明)→ 占位:
#todo-interview-multi-tz-sum - [ ] 题:对账告警日界抖时,分诊顺序为何把时区放在改口径之前?(考察点:与 recon-triage 衔接)→ 占位:
#todo-interview-multi-tz-triage