先给结论:不要试图把两个报表“改成同一个时区”再直接相减,而应先把两边都换算到同一个参照时区,再按参照时区的自然日重新聚合。如果做不到换算,就只能比较重叠时段,并明确标注“这不是完整一天”。判断该用哪种做法,取决于你手里有没有原始时间戳,以及两份报表的日期字段是“事件发生时间”还是“报表生成时间”。
常见的情形是:站内统计显示某天有 1200 次访问,广告后台显示同一天带来 900 次点击,差了 300。双方都认为自己没错,于是会议变成争论谁的数据可信。真正的原因往往不是谁造假,而是两份报表的“一天”不是同一个 24 小时。
假设站内统计按 UTC 切日,广告后台按北京时间(UTC+8)切日。那么站内的“10 月 1 日”覆盖北京时间 10 月 1 日 08:00 到 10 月 2 日 08:00;广告后台的“10 月 1 日”覆盖北京时间 10 月 1 日 00:00 到 24:00。两者有 16 小时重叠、8 小时错位。对不上是必然的,不是异常。
面对差异,通常有两种解释,需要不同的证据来区分。
解释一:时区切日不同。证据是:差异集中在跨日边界附近。你可以取北京时间 10 月 1 日 00:00–08:00 和 10 月 2 日 00:00–08:00 这两个“错位窗口”,看站内数据是否明显偏高或偏低。如果差异量大致等于这两个窗口的数据量,时区就是主因。
解释二:口径本身不同。比如站内统计的是“会话”,广告后台统计的是“点击”,一次点击可能不产生会话,一次会话也可能来自多次点击。证据是:即使把两边都换算到同一时区、同一时间窗,差异依然存在,且比例相对稳定。这时差异来自定义,而不是时间。
能同时排除两者的做法是:拿一份带原始时间戳的明细(哪怕只有几百行),自己按参照时区重新切日,再和两边报表比对。如果换算后差异大幅缩小,说明是时区问题;如果几乎没变,说明是口径问题。
第一步,确认每份报表的日期字段含义。是事件发生时间,还是报表按服务器时区汇总的日期?很多导出文件只给“日期”列,不给时区,这时要回到报表设置里看时区选项,而不是猜。
第二步,选一个参照时区。建议用业务主要受众所在的时区,或团队统一约定的时区,写进分析文档,避免下次再吵。
第三步,如果有原始时间戳,用代码统一换算后再聚合。例如把 UTC 时间戳转为北京时间:
beijing = utc_time + timedelta(hours=8)
然后按 beijing.date() 分组求和。这一步的结果会直接决定下一步:如果换算后差异消失,就更新报表口径说明;如果差异仍在,就转向核对指标定义,而不是继续纠缠时区。
第四步,如果拿不到原始时间戳,只能比较重叠时段。此时要在报表里显式写出“本对比仅覆盖重叠的 16 小时”,不要把它当成全天结论。
当多个角色对“一天的数据”理解不同时,与其争论,不如把分歧拆成可核对的项目:
这四项一旦写清楚,差异通常能被解释,而不是被“平均掉”。需要提醒的是,某项统计归零或骤降,不能单独证明时区处理正确——也可能是采集中断、过滤规则变化或数据延迟,需要结合上面几项证据一起看。
最后,把对齐规则固定下来:参照时区、换算方式、重叠时段标注方式。下一次再出现两边对不上,先查这几条,而不是重新开一次会。这样,时区差异就从“谁对谁错”的问题,变成了一个可以复核的项目。