维度时间属性与时区
维度里的时间戳属性(注册时间、开业时间、最后变更时间)必须标注时区基准,否则不同系统各按本地时间写入,跨区汇总时无法解释差异。通行做法是统一按 UTC 存储,再按业务时区派生本地时间列;跨时区业务还要把「业务日」的定义写清楚——按哪个时区切分自然日。
基本信息
| 存储基准 | 统一 UTC,列名标注 _utc |
|---|---|
| 派生列 | 按业务时区派生的本地时间,列名标注 _local |
| 业务日定义 | 明确按哪个时区切日,写入模型文档 |
| 夏令时 | 切换日本地时间会出现重复或缺失小时 |
| 命名建议 | create_ts_utc / create_ts_local 成对出现 |
| 常见函数 | Spark SQL 用 from_utc_timestamp,MySQL 用 CONVERT_TZ |
典型使用场景
- 跨国门店:营业日按门店当地时间判定,而非总部时间
- 订单归日:跨境订单按下单地时区归入销售日报
- 履约时效:计算签收时长时统一到 UTC,避免跨区相减出错
- 财务结账:不同法人主体按当地日历结账,报表需可切换时区
- 任务调度:批处理按业务时区切分日期分区,避免落错分区
UTC 存储与本地时间派生
UTC 存储与本地时间派生
SELECT order_id,
create_ts_utc,
from_utc_timestamp(create_ts_utc, 'Asia/Shanghai') AS create_ts_local_cn,
from_utc_timestamp(create_ts_utc, 'America/New_York') AS create_ts_local_us -- 同一时刻按不同时区展示
FROM dwd_order;
SELECT to_date(from_utc_timestamp(create_ts_utc, 'Asia/Shanghai')) AS biz_date, -- 业务日按业务时区切分
count(1) AS ord_cnt
FROM dwd_order
GROUP BY to_date(from_utc_timestamp(create_ts_utc, 'Asia/Shanghai'));时区处理要点
| 环节 | 做法 | 出错表现 |
|---|---|---|
| 入库 | 统一转 UTC 后落库 | 混合本地时间,跨区汇总偏差 |
| 分区 | 按业务时区计算 dt | 跨日订单落到错误日分区 |
| 展示 | 按用户所在时区派生 | 同一订单在不同报表显示不同日期 |
| 结算 | 以 UTC 或约定基准对齐 | 夏令时期间对账差一小时 |
夏令时地区的本地时间在切换日会出现重复小时(秋季回拨)或缺失小时(春季前拨),因此跨时区结算、计费、时长计算不要直接用本地时间相减,应以 UTC 或带时区偏移的时间戳为准。
「业务日」不是一个技术细节而是业务口径:例如电商的销售日通常按下单地时间,物流的派送日按目的地时间,两个口径都要在模型文档里写明,报表命名上也应体现。