Unix时间戳是什么、为什么会存在

Unix时间戳看起来只是一个很大的数字,但正是这个数字,让计算机能够可靠地处理日期和时间。

Unix时间是从一个固定起点开始计的秒数

Unix时间计算的是从1970年1月1日UTC零点(通常称为"纪元")到现在经过的秒数。历史上任何一个时刻,不管读取这个数字的人身处哪个时区,都对应唯一一个确定的整数。

秒和毫秒的混用是常见的bug来源

许多系统层面的工具使用秒为单位,而许多网页应用和JavaScript接口使用毫秒为单位。同一个时刻的数值,会因为对应系统预期的单位不同,而看起来恰好相差1000倍,这是实际开发中最常见的时间戳相关bug之一。

原始时间戳本身不携带任何时区信息

这个数字本身完全不包含时区概念,时区只有在把这个数字转换成人类可读的日历日期时才会被引入。这正是时间戳能够在不同地区之间一致地存储和比较时间的原因。

展示时通常会和ISO 8601格式配合使用

原始时间戳经常会与2026-09-21T00:00:00Z这样的ISO 8601格式互相转换,用于给人展示可读的日期,因为ISO 8601既方便机器解析,也方便人阅读。

1970年以前的日期用负数表示

纪元之前的时刻用负整数表示,这套格式本身可以顺畅地延伸到遥远的未来,不过部分较旧的系统会施加一些硬性的技术上限。

2038年问题

把Unix时间存储为带符号32位整数的系统,会在2038年1月19日发生溢出。这是一个已知的局限,有时会被拿来和Y2K问题类比,主要影响仍在使用32位方式存储时间的老旧软件以及部分嵌入式、遗留系统。

为什么软件用一个巨大的数字而不是日历日期来存时间

把时间存储成一个单一整数,而不是结构化的日期对象,能让两个时刻的比较、事件列表的排序,以及计算经过时间(比如"这两个事件之间相隔多少秒")都变成简单的四则运算,而不是需要考虑日历规则的复杂计算。这种方式还能在人真正需要读取这个数值之前,完全回避掉时区和日期格式方面的歧义。

实际开发中在哪些地方会遇到原始Unix时间戳

日志文件、数据库记录、接口返回结果、URL参数、Cookie过期时间等,通常都会用原始Unix数字而不是格式化好的日期字符串来存储时间,原因正是它足够紧凑、没有歧义,而且便于比较。把这个原始数字转换成可读的形式,是软件开发中最常见的日常任务之一。

常见问题

为什么我的时间戳数值看起来恰好相差1000倍?

这几乎总是秒和毫秒混淆造成的。根据接收方系统实际期望的格式,把数值乘以1000或除以1000即可。

换个时区,Unix时间戳的数值会变吗?

不会。对同一个时刻而言,不管身处世界哪个地方,这个底层数字都是完全相同的。会变的只是根据转换时所应用的时区,显示出来的那串人类可读的日期时间字符串。