一文搞懂时刻、时间戳、时间

张开发
2026/4/16 12:08:15 15 分钟阅读

分享文章

一文搞懂时刻、时间戳、时间
这些问题的根源通常在于对时刻Moment、时间戳Timestamp和本地时间Local Time这几个核心概念的混淆。本文将带你彻底理清这些概念。基本概念#什么是“时刻”#时刻Moment是宇宙时间轴上的一个绝对点。想象一下2026年世界杯决赛进球的一瞬间全球观众都在欢呼。对于此时此刻伦敦的观众看到钟表指向 23:00意大利的观众看到的是次日 00:00北京的观众看到的是次日 07:00。虽然各地的表盘读数不同但这一“瞬间”在物理上是唯一的。这种唯一性就是我们程序逻辑中需要锁定的核心。时间戳Timestamp#为了在计算机中客观地表示这个“唯一时刻”我们引入了时间戳。时间戳Unix Timestamp是指从1970年01月01日 00:00:00 UTC起至现在的总秒数或毫秒数。时间戳是一个绝对数值它不属于任何时区。无论你在纽约、伦敦还是北京在同一物理时刻获取到的 Unix 时间戳一定是完全相同的。它就像一把公用的刻度尺记录的是距离“原点”的物理距离。如果有同事说给你传东八的时间戳 那就是理解错了。本地时间#当我们说当前时刻是2026年1月5日早上7:00的时候我们说的实际上是本地时间。在国内就是北京时间。在这个时刻如果地球上不同地方的人们同时看一眼手表他们各自的本地时间是不同的伦敦 2026-01-04 23:00:00意大利 2026-01-05 00:00:00北京 2026-01-05 07:00:00所以不同的时区在同一时刻本地时间是不同的。全球一共分为24个时区伦敦所在的时区称为标准时区其他时区按东西偏移的小时区分北京所在的时区是东八区。时区#因为光靠本地时间还无法唯一确定一个准确的时刻所以我们还需要给本地时间加上一个时区。时区有好几种表示方式。一种是以GMT或者UTC加时区偏移表示例如GMT08:00或者UTC08:00表示东八区。UTC0 2026-01-04 23:00:00UTC1 2026-01-05 00:00:00UTC8 2026-01-05 07:00:00GMT和UTC可以认为基本是等价的只是UTC使用更精确的原子钟计时每隔几年会有一个闰秒我们在开发程序的时候可以忽略两者的误差因为计算机的时钟在联网的时候会自动与时间服务器同步时间。另一种是缩写例如CST表示China Standard Time也就是中国标准时间。但是CST也可以表示美国中部时间Central Standard Time USA因此缩写容易产生混淆我们尽量不要使用缩写。最后一种是以洲城市表示例如Asia/Shanghai表示上海所在地的时区。特别注意城市名称不是任意的城市而是由国际标准组织规定的城市。时刻相同的意思就是分别在两个时区的两个人如果在这一刻通电话他们各自报出自己手表上的时间虽然本地时间是不同的但是这两个时间表示的时刻是相同的。夏令时#时区还不是最复杂的更复杂的是夏令时。所谓夏令时就是夏天开始的时候把时间往后拨1小时夏天结束的时候再把时间往前拨1小时。因为涉及到夏令时相同的时区如果表示的方式不同转换出的时间是不同的。我们举个例子意大利的夏令时通常从每年3月的最后一个星期日开始到10月的最后一个星期日结束。开始时间2025年3月30日星期日凌晨2点意大利将进入夏令时届时所有时钟需拨快一个小时直接跳到3点此时可以理解为GMT2的时间。结束时间2025年10月26日星期日凌晨3点夏令时结束时钟需拨回一个小时调整为2点此时可以理解为GMT1的时间。所以对于2025-4-1和2025-10-27两个日期来说假设北京人在意大利如果以GMT或者UTC作为时区无论日期是多少时间都是19:00如果以国家城市表示例如Europe/Rome虽然意大利也在东一区但是因为夏令时的存在在不同的日期GMT时间和意大利时间可能是不一样的时区2025-4-12025-10-27GMT01:0019:0019:00UTC01:0019:0019:00Europe/Rome20:0019:00实行夏令时的不同地区进入和退出夏令时的时间很可能是不同的。同一个地区根据历史上是否实行过夏令时标准时间在不同年份换算成当地时间也是不同的。因此计算夏令时没有统一的公式必须按照一组给定的规则来算并且该规则要定期更新。逻辑关系一张图看懂转换#为了直观表达这种“多对一”的关系我画了下面这张图同一物理时刻UTC02026-01-04 23:00:00UTC12026-01-05 00:00:00UTC82026-01-05 07:00:001767567600000(Unix 时间戳自1970-01-01 00:00:00 UTC起的毫秒数)深度解析顶层物理现实代表宇宙中发生的一件事。中层表现形式由于观察者身处不同的时区Timezone同样的时刻被格式化成了不同的字符串。底层存储/交换标准无论表现形式如何最终在机器层面都会收敛为一个相同的时间戳如1767567600000。开发中的最佳实践#基于以上原理我们在开发时应遵循以下准则A. 后端存储永远使用 UTC 或 时间戳#在数据库如 MySQL, PostgreSQL中建议存储Long 型时间戳最稳妥完全避免时区转换开销。带时区的 Timestamp 类型由数据库底层处理 UTC 转换。禁止存储不带时区的本地时间字符串如2026-01-05 07:00:00因为没有时区信息这个字符串就是死数据无法还原回绝对时刻。B. 接口传输标准化 ISO 8601 或 时间戳#前后端交互时推荐使用Unix 时间戳毫秒级。ISO 8601 格式2026-01-05T07:00:0008:00。这种格式自带偏移量信息是可解析的。C. 前端展示根据用户时区转换#前端代码JS/Mobile接收到后端传来的绝对时刻时间戳后再调用系统 API 转换为用户当前所在时区的文字。// 无论后端在哪个时区传来的都是同一个 1767567600000 const timestamp 1767567600000; const date new Date(timestamp); console.log(date.toLocaleString()); // 自动根据用户电脑时区显示

更多文章