Unix 时间戳常见问题

对最常见的 Unix 时间戳问题的快速解答 —— 单位、时区处理、2038 年问题、各语言的转换等。

常见问题

关于 Unix 时间戳、纪元时间、时区以及如何正确存储时间的常见问题——按主题整理。把答案当作快速参考;更深入的指南链接在页面底部。

接下来去哪

FAQ

什么是 Unix 时间戳?
Unix 时间戳是自 Unix 纪元——1970 年 1 月 1 日 00:00:00 UTC——以来经过的秒数。它是一个与语言无关、与时区无关的整数,可唯一标识任意时刻。
什么是 Unix 纪元?
Unix 纪元是 1970 年 1 月 1 日 00:00:00 UTC。所有 Unix 时间戳都从这个固定参照点向前测量——负值则向后。选择 1970 年是出于实用考虑:在贝尔实验室设计 Unix 时,这是一个较近且整齐的年份。
10 位和 13 位时间戳有什么区别?
10 位时间戳(例如 1700000000)表示自纪元起的秒数。13 位时间戳(例如 1700000000000)表示毫秒。JavaScript 的 Date.now() 返回毫秒;大多数 Unix 系统调用以及 Python、Go、PHP 等语言默认返回秒。
为什么 JavaScript 使用毫秒而不是秒?
JavaScript 的 Date API 设计时是为了匹配 1995 年可用的系统计时器分辨率。使用毫秒可避免亚秒时长的精度损失。处理服务器生成的以秒为单位的 Unix 时间戳时,请在传给 new Date() 之前乘以 1000。
在 JavaScript 中如何把 Unix 时间戳转换为可读日期?
对于秒时间戳:new Date(1700000000 * 1000).toISOString()。对于毫秒时间戳:new Date(1700000000000).toISOString()。两者都生成形如 '2023-11-15T06:13:20.000Z' 的 ISO 8601 字符串。本地化显示请使用带 timeZone 选项的 toLocaleString()。
Unix 时间戳能感知时区吗?
不能。Unix 时间戳始终表示 UTC 中的单一时刻。时区信息仅在为显示而格式化时间戳时才应用。两台位于不同时区的设备对同一时刻会生成相同的 Unix 时间戳。
什么是 2038 年问题?
将 Unix 时间戳存为 32 位有符号整数的系统只能表示到 2,147,483,647 的值,对应 2038 年 1 月 19 日 03:14:07 UTC。过了那一刻,整数会溢出为一个很大的负数。现代 64 位系统不受影响,但嵌入式系统和遗留数据库可能仍有风险。
什么是负的 Unix 时间戳?
负的 Unix 时间戳表示 Unix 纪元之前的时刻。例如,-86400 是 1969 年 12 月 31 日 00:00:00 UTC。大多数现代日期 API 能正确处理负时间戳,但一些较旧的系统和数据库不支持它们。
在 Python 中如何获取 Unix 时间戳?
秒用 import time; int(time.time())。需要显式 UTC datetime:import datetime; int(datetime.datetime.now(datetime.timezone.utc).timestamp())。毫秒用:int(time.time() * 1000)。
Unix 时间戳的精度如何?
标准 Unix 时间戳为一秒精度。对于亚秒精度,毫秒时间戳(13 位)在 Web API 和 JavaScript 中很常见。有些系统使用微秒(16 位)或纳秒。合适的单位取决于你的应用实际需要的精度。
Unix 时间戳能有多大?
在 64 位有符号整数(如今的标准)上,Unix 时间戳可表示从约 2920 亿年前到 2920 亿年后的任意时刻。著名的 32 位限制(2038 年问题)只适用于遗留系统。
为什么我的时间戳显示 1970?
通常是三种原因之一:值为 0(纪元本身)、值是毫秒却被当作秒处理(于是被舍入到接近 0 的极小秒值),或值为 null/undefined 而你的代码默认将其设为 0。
UTC 和 GMT 有什么区别?
在大多数情况下 UTC 和 GMT 可互换。UTC(协调世界时)是现代原子标准;GMT(格林尼治标准时间)是表示零偏移时区的遗留术语。英国和大多数软件将二者视为等价。
应该把日期存为 Unix 时间戳还是 ISO 8601 字符串?
两者都行。Unix 整数紧凑且便于比较;ISO 8601 字符串自描述且人类可读。在数据库中,原生 datetime 类型(Postgres 的 TIMESTAMP WITH TIME ZONE、MySQL 的 DATETIME(6))通常最好,因为它们保留时区语义且能高效建立索引。
存储我服务器的本地时间安全吗?
不安全。在不带偏移的情况下存储本地时间,会在服务器迁移、DST 变更,或另一个时区的另一台服务器读取该值时丢失信息。请存储 UTC(作为 Unix 时间戳或带时区的 datetime),仅在显示层转换为本地时间。
Unix 时间戳包含闰秒吗?
POSIX Unix 时间有意忽略闰秒——即使插入一个额外的 UTC 秒,每个 Unix 日也正好是 86,400 秒。实际的秒编号会被重复,或者时钟被抹平,具体取决于系统。