专栏名称: 码农翻身
工作15年的前IBM架构师分享好玩有趣的编程知识和职场的经验教训, 不容错过。
目录
相关文章推荐
程序员小灰  ·  部署DeepSeek ... ·  昨天  
程序员小灰  ·  小灰筹划6年的“仓鼠币系统”,终于上线了! ·  3 天前  
程序猿  ·  患者带着DeepSeek来看病,医学博主自嘲 ... ·  3 天前  
程序员的那些事  ·  GPU:DeepSeek ... ·  2 天前  
OSC开源社区  ·  RAG市场的2024:随需而变,从狂热到理性 ·  3 天前  
51好读  ›  专栏  ›  码农翻身

50多年前,大神在操作系统中埋的雷,快要爆了......

码农翻身  · 公众号  · 程序员  · 2025-02-27 08:55

正文

1969年,贝尔实验室的大神Ken Thompson的老婆休假,带着儿子回娘家,时间长达三周。


趁这段时间,他决定开发一个操作系统:Unix。

(详情参见:《 漫画 | 老婆离家三周,我开发了一个操作系统 》)


正在如火如荼地敲代码的时候,Ken突然卡壳了,这是一件非同寻常的事情,之前的开发都是一帆风顺,行云流水的。


因为他意识到有个非常重大的问题,必须马上解决。


这个问题就是:如何在Unix中表示日期和时间?


这个问题非常重要,因为日期和时间管理对于任何操作系统来说都是关键功能,包括文件时间戳、程序调度、日志记录等。


最容易想到,也是最简单的办法就是用一个字符串来表示,例如:


1970-09-17 00:00:30.751


有年月日,时分秒,还有细粒度的微妙,并且可读性非常强。


但是这种方式明显不符合Unix的设计原则:简洁,一致性,易于使用。


原因很简单:


(1) 存储效率低下


字符串需要占用大量的空间,处理起来也更复杂


(2) 计算复杂性读比较高


比如要计算两个时间的差值,需要先解析字符串,然后进行更复杂的日期和时间计算。



解决办法


正当Ken一筹莫展之际,Dennis Ritchie端着咖啡走了过来:“兄台,遇到什么事情了?”


Ken把问题的来龙去脉讲了一遍。


Dennis沉吟道:“嗯,这确实是一个问题,得有一个简洁易用的,符合Unix设计原则的方案....”


突然,Dennis一拍大腿:“用一个整数来表示日期和时间怎么样?”


聪明异常的Ken立刻秒懂,眼睛发光:“对,先确定一个开始时间(纪元),然后这个整数表示从纪元开始到当前时间流逝的秒数!”


Dennis说:“这个纪元可以设定为: 1970年1月1日00:00:00 ,那个时候Unix肯定发布了。”


如果这个整数是: 1631280731 ,那就表示 2021-09-10 13:45:31 UTC



Ken Thompson决定把这种方式成为 Unix Epoch Time(Unix 纪元时间)


用一个整数来表示时间戳,有几个主要的优势:


(1) 简化


通过将日期和时间表示为一个单一的整数,可以大大简化日期和时间的计算。例如,计算两个日期之间的差异就只需要对两个整数进行减法运算。


(2) 便于存储和处理


整数易于存储(占用的空间较少)且便于在各种编程语言中处理。


(3) 兼容性


Unix时间戳可以在不同的操作系统和平台之间轻松地进行交换和比较。


(4) 全球统一


Unix时间戳是从同一时刻(1970年1月1日00:00:00 UTC)开始的,所以它提供了一种在全球范围内统一的时间表示方式。



问题出现



当然,Unix时间戳也有其限制。例如,它不能很好地处理闰秒,而且直接查看Unix时间戳并不能很好地理解当前的日期和时间。


在上世纪六七十年代,电脑主要还是16位的,Ken Thompson把Unix时间戳确定为32位整数,他觉得已经够大了,再说了谁会知道Unix操作系统能用多久呢?


让人想不到的是Unix一直存活了下来,它的很多概念对整个计算机科学和软件开发领域产生了深远的影响,包括时间和日期的处理方式。类Unix的开源操作系统Linux继承了Unix的衣钵,甚至统治了服务器端的OS市场。


开发Linux的时候,也是采用了32位的整数来记录时间戳。


现在一个大问题来了,32位的有符号整数最大值是2147483647 ,只能让我们用到 2038年1月19号 03:14:07 UTC



下面这个动图展示了整数溢出以后的效果:



这被称为 Y2K38 问题。







请到「今天看啥」查看全文