指南

为您的用户将 UTC 时间戳转换为本地时间

在数据库中以 UTC 存储时间戳是正确的做法。但在支持工单、订单确认或活动日志中向用户显示 UTC 就不对了,这是产品界面中较常见的小烦恼之一。

两步完成转换

第一步,确定应该以哪个地点来解读该时间戳,可以是档案中某个地址的坐标,也可以是 IP 查询得到的坐标。第二步,将这些坐标和 UTC 时间戳本身通过 time 参数传给 /v1/timezone,这样返回的偏移量对应的是所涉及的那个时刻,而不是当前时刻。

GET /v1/timezone?lat=40.7128&lon=-74.0060&time=1734000000
{
  "status": "ok",
  "timezone": "America/New_York",
  "utc_offset": "-05:00",
  "abbreviation": "EST"
}

将 utc_offset 应用到您存储的 UTC 时间戳上,或者把时区标识符传入您自己的日期格式化代码,然后显示转换后的结果,而不是原始的 UTC 值。

第二个示例,相隔数月

同样的坐标会因传入的时间戳不同而返回不同的偏移量,这正是 time 参数存在的全部理由。

GET /v1/timezone?lat=40.7128&lon=-74.0060&time=1719000000
{
  "status": "ok",
  "timezone": "America/New_York",
  "utc_offset": "-04:00",
  "abbreviation": "EDT"
}

请注意,对于完全相同的位置,两次调用之间的偏移量从负五小时变成了负四小时,原因仅仅是一个时间戳处于夏令时而另一个不是。如果显示时忽略这一点,对两者都套用同一个固定偏移量,那么其中一个就会差一个小时。

为什么 time 参数很重要

在大多数实行夏令时的地方,偏移量会在一年中发生变化。如果您调用端点时从不传 time 参数,得到的就是今天的偏移量,而这对六个月前的时间戳来说就是错的。当要转换的时间戳与当前时间可能位于夏令时切换的两侧时,请始终传入要转换的时间戳,而不是当前时间。

缓存时区,而不是偏移量

一组坐标对应的时区标识符很少改变,因此可以放心地把 timezone 字符串本身按位置缓存。utc_offset 和 abbreviation 的值则不宜长期缓存,因为它们会随夏令时变化,所以请在显示时重新计算,而不是存储它们。

一个值得了解的边界情况

并不是每个地方都实行夏令时。全年保持固定偏移量的地方,无论您传入哪个时间戳,都会返回相同的 utc_offset,这是预期行为,并不表示 time 参数被忽略了。不要因为两个不同时间戳得到相同结果就认为出了问题。

请求成本

一次转换就是一个请求。需要一次为大量已存储记录转换时间的控制台,应通过批量 POST 提交底层坐标,而不是逐个时间戳循环调用,这样每项仍然计为一个请求,但只需一次调用。

把当地时间处理正确,比大多数团队预想的更重要,直到某张支持工单显示了错误的钟点才会意识到。请求和响应字段的详细说明见时区查询文档