1. 基础知识
1.1 UTC (Coordinated Universal Time) - 协调世界时
- 这是什么? UTC 是全世界的时间标准,是“零号时区”的基准。你可以把它想象成时间的“世界普通话”。它不受任何地区或夏令时的影响,永远稳定、中立。
- 和 GMT 的区别? 很多人会混用 UTC 和 GMT(格林尼治标准时间)。在日常使用中,你可以认为它们是等价的。严格来说,GMT 是基于地球自转的天文时间,而 UTC 是基于原子钟的更精确的物理时间。在计算机领域,我们只用 UTC。
- 关键点: 当我们讨论一个绝对、无歧义的时间点时,我们说的就是 UTC 时间。
1.2 时区 (Time Zone)
- 这是什么? 时区是地球上某个区域使用的标准时间。它通常表示为与 UTC 的偏移量(Offset)。
- 举例:
- 中国标准时间 (CST) =
UTC+8
。意思是,北京时间比 UTC 时间早 8 个小时。 - 纽约的东部标准时间 (EST) =
UTC-5
。意思是,纽约时间比 UTC 时间晚 5 个小时。
- 中国标准时间 (CST) =
- 计算一下: 如果现在的 UTC 时间是
10:00
,那么:- 北京时间是
10:00 + 8小时** = 18:00
。 - 纽约时间是
10:00 - 5小时 = 05:00
。
- 北京时间是
1.3 夏令时 (Daylight Saving Time - DST)
- 这是什么? 这是最让人头疼的部分!为了节约能源,某些国家和地区会在夏季将时钟拨快一小时。这意味着,一个地区的 UTC 偏移量会发生变化。
- 举例(纽约):
- 冬季,纽约使用东部标准时间 (EST),即
UTC-5
。 - 夏季(大约 3 月到 11 月),纽约实行夏令时,改用东部夏令时间 (EDT),即
UTC-4
。
- 冬季,纽约使用东部标准时间 (EST),即
- 关键点: 夏令时的开始和结束日期每年都可能不同,而且由各国政府决定。中国目前不实行夏令时。
1.4 IANA 时区数据库 (tz database)
- 这是什么? 既然夏令时这么复杂,计算机怎么知道纽约现在是
UTC-4
还是UTC-5
呢?答案就是 IANA 时区数据库。 - 它不是一个简单的偏移量,而是一套规则集。它记录了全球所有地区从过去到现在的时区变化历史和未来的夏令时规则。
- 命名方式: 它使用
大洲/城市
的格式,例如Asia/Shanghai
或America/New_York
。 - 为什么这很重要? 你永远不应该只使用
EST
或CST
这样的缩写,因为它们有歧义(比如 CST 可以是中国的 Central Standard Time,也可以是美国的 Central Standard TimeUTC-6
)。而America/New_York
这样的名称是唯一的,并且包含了所有的夏令时规则。
1.5 时间戳 (Timestamp) - 终极武器
Unix 时间戳(或称 Epoch 时间)是指从 格林尼治时间 1970 年 1 月 1 日 00:00:00 UTC 这个“纪元”时刻起,到现在的总秒数(有时也用毫秒、微秒)。
它是一个纯粹的数字,通常是一个很大的整数。
- 绝对无歧义: 一个时间戳在全球任何地方、任何系统上都代表着完全相同的那个瞬间。它不包含任何时区或夏令时信息,因为它本身就是基于 UTC 的。
- 易于计算和比较: 比较两个时刻的早晚,就是比较两个数字的大小。计算时间差,就是做减法。非常高效。
- 易于存储和传输: 数据库里存一个数字,远比存一个复杂的日期时间字符串要简单、可靠。API 之间传递一个数字,也不会有解析错误。
1.6 时间戳原理
- 你在北京,你的电脑时区设置为
Asia/Shanghai
(UTC+8
)。 - 你在日历上创建了一个事件:“2025 年 7 月 27 日 上午 10:00”。
- 你的电脑会这样做:
- “好的,本地时间是
2025-07-27 10:00
,时区是UTC+8
。” - “把它转换成 UTC 时间:
10:00 - 8小时 = 02:00
。所以 UTC 时间是2025-07-27 02:00:00 UTC
。” - “再把这个 UTC 时间转换成 Unix 时间戳。”(例如,得到一个数字
1753572000
) - 你的日历软件将 时间戳
1753572000
发送到服务器。服务器不需要关心你是哪个时区的,它只保存这个纯粹的数字。 - 服务器再把这个时间戳同步给你在纽约的朋友。
- 你朋友的电脑时区设置为
America/New_York
。在 7 月份,这个时区实行夏令时,所以是UTC-4
。 - 他的电脑接收到时间戳
1753572000
。 - 他的电脑会这样做:
- “好的,收到了一个时间戳,先把它转回 UTC 时间:
2025-07-27 02:00:00 UTC
。” - “然后,根据我当前的
America/New_York
时区 (UTC-4
),把它转换成本地时间。” - “计算:
UTC时间 02:00 - 4小时 = 前一天晚上的 22:00
。”
- “好的,收到了一个时间戳,先把它转回 UTC 时间:
- 最终,你朋友的日历上会显示:“2025 年 7 月 26 日 晚上 10:00”。
2. 知识点
2.1 时区不是一个偏移量
错误观念: 认为时区就是一个固定的偏移量,比如 +8
。
- 为什么错? 这忽略了夏令时的存在。
America/New_York
才是真正的时区,它包含了UTC-5
和UTC-4
之间的切换规则。 - ✅ 正确做法: 在需要处理具体本地时间时,使用 IANA 时区名称(
Area/City
),让标准库帮你处理复杂的夏令时计算。
2.2 计算机黄金法则
后端思考用 UTC,传输存储用时间戳,前端显示用本地时区。
(Think in UTC, Store/Transmit in Timestamp, Display in Local Time.)
2.3 ISO 8601 格式
1 | # z 代表 UTC 时区 |
- 格式:
YYYY-MM-DDTHH:mm:ss.sssZ
或者YYYY-MM-DDTHH:mm:ss.sss±hh:mm
YYYY-MM-DD
:年月日T
:一个分隔符,用来隔开日期和时间。HH:mm:ss.sss
:时分秒和毫秒Z
:最关键的部分!Z
代表Zulu Time
,也就是 UTC 时间。±hh:mm
:如果不是 UTC 时间,则用偏移量来表示,比如+08:00
。
- 示例:
2025-07-26T12:00:00Z
(表示 UTC 时间的中午 12 点)2025-07-26T20:00:00+08:00
(表示东八区晚上 8 点,它和上面那个时间是同一个瞬间!)
- 为什么重要: 在 API 接口、日志文件、数据交换中,这是最推荐、最不会出错的字符串格式。
3. 提问问题
3.1 GMT 是什么
一句话总结:GMT 是基于地球自转、以伦敦格林尼治为零点的世界时间基准。在历史上,它就是“世界时”的代名词。在现代计算机和科学领域,GMT 已经“退休”,UTC 才是“现役军”。
在日常口语和非严格场合,你可以把 GMT 和 UTC 看作是等价的,它们都代表着那个“零号时区”的时间。比如 UTC+8
和 GMT+8
在实际使用中表达的是一个意思。
GMT 的“秒”来自于不那么稳定的天文观测,而 UTC 的“秒”来自于极其稳定的物理实验。因此,从根本上说,它们是两个不同的测量系统。
3.2 UTC 是时区的概念吗?
UTC 不是时区的概念。UTC+8 也不完全是“时区”本身,而更准确地说是“时区偏移量”。
- 时区 (Time Zone) 是一个地理概念。它指的是地球上的一块区域,这个区域内的所有地方都同意使用同一个本地时间。例如
Asia/Shanghai
是一个时区,它规定了这个区域使用比 UTC 快 8 小时的时间。 - UTC (Coordinated Universal Time) 是一个时间标准 (Time Standard)。它不是任何地方的本地时间,而是所有本地时间计算的参考基准或零点。
3.2 夏令时的好处是什么
“我们早上浪费了那么多宝贵的阳光,晚上又不得不花钱点灯。为什么我们不从早上‘借’一个小时的阳光,然后‘还’到晚上去用呢?晚上一小时天黑,就能少开一小时的灯,从而节省电力。尤其是在战争时期,节省能源是国家大事。
为了应对这该死的复杂性,所有的操作系统、数据库、软件都需要一个庞大且不断更新的 IANA 时区数据库 (tz database)。你的手机
和电脑之所以能自动调整时间,就是因为背后有程序员在不断维护这个数据库。一旦更新不及时,就会出现各种 bug。
因为它是一个源于工业时代前期的美好设想,却在一个高度全球化、数字化、能源结构完全不同的现代社会里,变成了一个缺乏统一标准、弊大于利的“历史遗留问题”。
3.4 冷门知识点
- 你以为时区偏移量都是整小时的?
- 太天真了!半小时偏移: 印度、斯里兰卡是
UTC+5:30
;澳大利亚中部的达尔文是UTC+9:30
。
- 太天真了!半小时偏移: 印度、斯里兰卡是
- 闰秒
- 闰秒是偶尔运用于协调世界时(UTC)的调整,经由增加或减少一秒,以消弥精确的时间(使用原子钟测量)和不精确的观测太阳时(称为 UT1),之间的差异。
- 为了让我们的“时钟时间”(UTC) 和“地球时间”(UT1) 的差距保持在 0.9 秒以内,科学家们会不定期地在全球时间里增加一秒。
- 由于麻烦太大,国际社会已经投票决定最晚于 2035 年停止使用闰秒。