首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >到了2038年时间戳溢出了怎么办?

到了2038年时间戳溢出了怎么办?

原创
作者头像
程序饲养员
发布于 2023-12-28 03:22:00
发布于 2023-12-28 03:22:00
1.8K0
举报
文章被收录于专栏:风骚语言Rust风骚语言Rust

计算机中的时间

看完这篇文章相信你会对计算机中的时间有更系统全面的认识。

我经常自嘲,自己写的程序运行不超过3年,因为大部分项目方就早早跑路了。大多数项目上线后,你跟这个项目就再无瓜葛,关于时间你只需要保证时区正确就不会有太大问题,哈哈。 但是今天我想认真对待时间这个问题,作为一个库作者或基础软件作者,就需要考虑下游项目万一因为你处理时间不当而造成困扰,影响范围就比较广了。

计算机中与时间有关的关键词:

代码语言:js
AI代码解释
复制
时间类型
时间戳(timestamp)
定时器(例如js中setInterval())
时间计算
时间段
超时(setTimeout())
时间片
GMT
UTC
Unix时间戳
ISO8601
CST
EST

看到这些你可能会疑惑,为何一个时间竟然如此复杂!!

如果下面的问题你都能答上来,那这篇文章对你的帮助微乎其微,不如做些更有意义的事情。

  • 常用的时间格式,他们都遵循哪些标准?
  • 什么是GMT?
  • 什么是UTC?
  • GMT UTC 和ISO8601有什么区别?
  • RFC5322是什么?
  • RFC5322 采用的是GMT还是UTC?
  • ISO8601 使用的是UTC还是GMT?
  • 在ISO8601中 Z可以使用+00:00表示吗?
  • UTC什么时候校准?
  • CST是东八区吗?
  • Z是ISO 8601规定的吗,为什么是Z?
  • 时区划分是哪个标准定义的?
  • 为什么是1970年1月1日呢?
  • 到了2038年时间戳溢出了怎么办?
  • 计算机中时间的本质是一个long类型吗?
  • WEB前后端用哪个格式传输好?
  • '2024-01-01T24:00:00' 等于 '2024-01-02T00:00:00' ??

如果看文章太累,也可以B站搜 程序饲养员 看《计算机中的时间》那期视频。

正文开始

1. 两种时间标准

UTC和GMT都是时间标准,定义事件的精度。它们只表示 零时区 的时间,本地时间则需要与 时区 或偏移 结合后表示。这两个标准之间差距通常不会超过一秒。

UTC(协调世界时)

UTC,即协调世界时(Coordinated Universal Time),是一种基于原子钟的时间标准。它的校准是根据地球自转的变化而进行的,插入或删除闰秒的实际需求在短期内是难以预测的,因此这个决定通常是在需要校准的时候发布。 闰秒通常由国际电信联盟(ITU) 和国际度量衡局(BIPM) 等组织进行发布。由国际原子时(International Atomic Time,TAI) 通过闰秒 的调整来保持与地球自转的同步。

GMT(格林尼治标准时间)

以英国伦敦附近的格林尼治天文台(0度经线,本初子午线)的时间为基准。使用地球自转的平均速度来测量时间,是一种相对于太阳的平均时刻。尽管 GMT 仍然被广泛使用,但现代科学和国际标准更倾向于使用UTC。

2. 两种显示标准

上面我们讨论的时间标准主要保证的是时间的精度,时间显示标准指的是时间的字符串表示格式。我们熟知的有 RFC 5322 和 ISO 8601。

RFC 5322 电子邮件消息格式的规范

RFC 5322 的最新版本是在2008年10月在IETF发布的,你阅读时可能有了更新的版本。

RFC 5322 是一份由 Internet Engineering Task Force (IETF) 制定的标准,定义了 Internet 上的电子邮件消息的格式规范。该标准于2008年发布,是对之前的 RFC 2822 的更新和扩展。虽然 RFC 5322 主要关注电子邮件消息的格式,但其中的某些规范,比如日期时间格式,也被其他领域采纳,例如在 HTTP 协议中用作日期头部(Date Header)的表示。

格式通常如下:

代码语言:js
AI代码解释
复制
Thu, 14 Dec 2023 05:36:56 GMT

时区部分为了可读可以如下表示:

代码语言:js
AI代码解释
复制
Thu, 14 Dec 2023 05:36:56 CST
Thu, 14 Dec 2023 05:36:56 +0800
Thu, 14 Dec 2023 05:36:56 +0000
Thu, 14 Dec 2023 05:36:56 Z

但并不是所有程序都兼容这种时区格式,通常程序会忽略时区,在写程序时要做好测试。标准没有定义毫秒数如何显示。

需要注意的是,有时候我们会见到这种格式Tue Jan 19 2038 11:14:07 GMT+0800 (中国标准时间),这是js日期对象转字符串的格式,它与标准无关,千万不要混淆了。

ISO 8601

ISO 8601 最新版本是 ISO 8601:2019,发布日期为2019年11月15日,你阅读时可能有了更新的版本。

下面列举一些格式示例:

代码语言:js
AI代码解释
复制
2004-05-03T17:30:08+08:00
2004-05-03T17:30:08+00:00
2004-05-03T17:30:08Z
2004-05-03T17:30:08.000+08:00

标准并没有定义小数位数,保险起见秒后面一般是3位小数用来表示毫秒数。 字母 "Z" 是 "zero"(零)的缩写,因此它被用来表示零时区,也可以使用+00:00,但Z更直观且简洁。

  1. 本标准提供两种方法来表示时间:一种是只有数字的基础格式;第二种是添加了分隔符的扩展格式,更易读。扩展格式使用连字符“-”来分隔日期,使用冒号“:”来分隔时间。比如2009年1月6日在扩展格式中可以写成"2009-01-06",在基本格式中可以简单地写成"20090106"而不会产生歧义。 若要表示前1年之前或9999年之后的年份,标准也允许有共识的双方扩展表达方式。双方应事先规定增加的位数,并且年份前必须有正号“+”或负号“-”而不使用“。依据标准,若年份带符号,则前1年为"+0000",前2年为"-0001",依此类推。
  2. 午夜,一日的开始:完全表示为000000或00:00:00;仅有小时和分表示为0000或00:00
  3. 午夜,一日的终止:完全表示为240000或24:00:00;仅有小时和分表示为2400或24:00
  4. 如果时间在零时区,并恰好与UTC相同,那么在时间最后加一个大写字母Z。Z是相对协调世界时时间0偏移的代号。 如下午2点30分5秒表示为14:30:05Z或143005Z;只表示小时和分,为1430Z或14:30Z;只表示小时,则为14Z或14Z。
  5. 其它时区用实际时间加时差表示,当时的UTC+8时间表示为22:30:05+08:00或223005+0800,也可以简化成223005+08。

日期与时间合并表示时,要在时间前面加一大写字母T,如要表示东八区时间2004年5月3日下午5点30分8秒,可以写成2004-05-03T17:30:08+08:00或20040503T173008+08。

在编写API时推荐使用ISO 8601标准接收参数或响应结果,并且做好时区测试,因为不同编程语言中实现可能有差异。

时区划分和偏移

全球被分为24个时区,每个时区对应一个小时的时间差。 时区划分由IANA维护和管理,其时区数据库被称为 TZ Database(或 Olson Database)。这个数据库包含了全球各个时区的信息,包括时区的名称、标识符、以及历史性的时区变更数据,例如夏令时的开始和结束时间等。在许多操作系统(如LinuxUnix、macOS等)和编程语言(如Java、Python等)中得到广泛应用。

TZ Database具体见我整理的表格,是从Postgresql中导出的一份Excel

时区标识符采用"洲名/城市名"的命名规范,例如:"America/New_York"或"Asia/Shanghai"。这种命名方式旨在更准确地反映时区的地理位置。时区的具体规定和管理可能因国家、地区、或国际组织而异。

有一些时区是按照半小时或15分钟的间隔进行偏移的,以适应地理和政治需求。在某些地区,特别是位于边界上的地区,也可能采用不同的时区规则。

EST,CST、GMT(另外一个含义是格林尼治标准时间)这些都是时区的缩写。

这种简写存在重复,如CST 可能有多种不同的含义,China Standard Time(中国标准时间),它对应于 UTC+8,即东八区。Central Standard Time(中部标准时间) 在美国中部标准时间的缩写中也有用。中部标准时间对应于 UTC-6,即西六区。因此在某些软件配置时不要使用简称,一定要使用全称,如”Asia/Shanghai“。

采用东八区的国家有哪些

  • 中国: 中国标准时间(China Standard Time,CST)是东八区的时区,对应于UTC+8。
  • 新加坡: 新加坡位于东八区,使用UTC+8。
  • 马来西亚: 马来西亚的半岛部分和东马来西亚位于东八区,使用UTC+8。
  • 菲律宾: 菲律宾采用东八区的时区,对应于UTC+8。

计算机系统中的时间 —— Unix时间戳

Unix时间戳(Unix timestamp)定义为从1970年01月01日00时00分00秒(UTC)起至现在经过的总秒数(秒是毫秒、微妙、纳秒的总称)。

这个时间点通常被称为 "Epoch" 或 "Unix Epoch"。时间戳是一个整数,表示从 Epoch 开始经过的秒数。

一些关键概念:

  1. 起始时间点: Unix 时间戳的起始时间是 1970 年 1 月 1 日 00:00:00 UTC。在这一刻,Unix 时间戳为 0。
  2. 增量单位: Unix 时间戳以秒为单位递增。每过一秒,时间戳的值增加 1。
  3. 正负值: 时间戳可以是正值或负值。正值表示从 Epoch 开始经过的秒数,而负值表示 Epoch 之前的秒数。
  4. 精度: 通常情况下,Unix 时间戳以整数形式表示秒数。有时也会使用浮点数表示秒的小数部分,以提供更精细的时间分辨率。精确到秒是10位;有些编程语言精确到毫秒是13位,被称为毫秒时间戳。

为什么是1970年1月1日?

这个选择主要是出于历史和技术的考虑。

Unix 操作系统的设计者之一,肯·汤普森(Ken Thompson)和丹尼斯·里奇(Dennis Ritchie)在开发 Unix 操作系统时,需要选择一个固定的起始点来表示时间。1970-01-01 00:00:00 UTC 被选为起始时间。这个设计的简洁性和通用性使得 Unix 时间戳成为计算机系统中广泛使用的标准方式来表示和处理时间。

时间戳为什么只能表示到2038年01月19日03时14分07秒?

在许多系统中,结构体time_t 被定义为 long,具体实现取决于编译器和操作系统的架构。例如,在32位系统上,time_t 可能是32位的 long,而在64位系统上,它可能是64位的 long。 32位有符号long类型,实际表示整数只有31位,最大能表示十进制2147483647(01111111 11111111 11111111 11111111)。

代码语言:js
AI代码解释
复制
> new Date(2147483647000)
< Tue Jan 19 2038 11:14:07 GMT+0800 (中国标准时间)

实际上到2038年01月19日03时14分07秒,便会到达最大时间,过了这个时间点,所有32位操作系统时间便会变为10000000 00000000 00000000 00000000。因具体实现不同,有可能会是1901年12月13日20时45分52秒,这样便会出现时间回归的现象,很多软件便会运行异常了。

至于时间回归的现象相信随着64为操作系统的产生逐渐得到解决,因为用64位操作系统可以表示到292,277,026,596年12月4日15时30分08秒。

另外,考虑时区因素,北京时间的时间戳的起始时间是1970-01-01T08:00:00+08:00。

好了,关于计算机中的时间就说完了,有疑问评论区相见

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
UTC时间戳与北京时间转换
在应用中用到了 UTC 时间戳与北京时间进行转换的需求,这里做一个记录,方便后面有需求时直接拿来用。
Gnep@97
2023/10/31
4.5K0
UTC时间戳与北京时间转换
GMT UTC CST ISO 夏令时 时间戳,都是些什么鬼?
日期/时间的处理是平时开发中非常常见的场景,若只是简单的格式化场景那就还好,一旦涉及到时区、跨地域跨时区时间转换场景,甚至当还有GMT时间、UTC时间等一堆概念堆上来的时候,总是心理发虚,招架不住。
YourBatman
2021/01/19
3.7K0
GMT UTC CST ISO 夏令时 时间戳,都是些什么鬼?
遇到的各种时间类型:UTC时间、GMT时间、本地时间、Unix时间戳
GMT,即格林尼治标准时间,也就是世界时。GMT的正午是指当太阳横穿格林尼治子午线(本初子午线)时的时间。但由于地球自转不均匀不规则,导致GMT不精确,现在已经不再作为世界标准时间使用。
陈大剩博客
2023/02/17
4K0
遇到的各种时间类型:UTC时间、GMT时间、本地时间、Unix时间戳
什么是时区?
1884年在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东、西各12个时区)。规定英国(格林尼治天文台旧址)为中时区(零时区)、东1-12区,西1-12区。每个时区横跨经度15度,时间正好是1小时。
JMCui
2023/03/02
2.4K0
什么是时区?
扩展学习之时间戳趣谈
Unix时间戳(英文为Unix epoch, Unix time, POSIX time 或 Unix timestamp),是从1970年1月1日(UTC/GMT的午夜)开始到现在所经过的秒数(格林威治时间1970年01月01日00时00分00秒、北京时间1970年01月01日08时00分00秒),不考虑闰秒。
chimchim
2023/10/17
1.1K0
扩展学习之时间戳趣谈
【踩坑】服务器和本地相差8小时
如果添加的该条数据的时间区间在数据库中已经有重叠的区间,那么就不允许添加,但是在添加的数据的时候,明明添加并没有这个区间,但是一直提示已经存在数据
神仙朱
2021/07/20
8.3K1
Linux|容易迷糊的时间戳事件
起因是在排错的时候,同事说log的时间不对,通过解析时间戳怎么是中国的时间巴拉巴拉的,理论上应该是设备所在的当地时间。
琉璃康康
2024/02/01
9990
Linux|容易迷糊的时间戳事件
系统设计中 跨时区问题 解决方案
产品功能设计中,经常会遇到一场活动,分跨不同时区,系统需要显示不同时区的时间,同时希望跨时区的用户可以同一时间开始,同一时间结束。
架构精进之路
2024/04/30
1.1K0
系统设计中 跨时区问题 解决方案
三句话理解时区与时间戳
时间不分东西南北、在地球的每一个角落都是相同的。他们都有一个相同的名字,叫时间戳。时间戳 指的就是Unix时间戳(Unix timestamp)。它也被称为Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
chengcheng222e
2021/11/04
4.4K0
漫话:为什么计算机起始时间是1970年1月1日?
1970-01-01对于开发者来说都是不陌生的,有些系统对于时间的处理如果不够好的话,就可能把时间显示成1970-01-01,所以经常有用户看到1970-01-01这个时间。
帅地
2020/05/19
27.5K2
漫话:为什么计算机起始时间是1970年1月1日?
GMT UTC CST ISO 夏令时 时间戳,都是些什么鬼?
日期/时间的处理是平时开发中非常常见的场景,若只是简单的格式化场景那就还好,一旦涉及到时区、跨地域跨时区时间转换场景,甚至当还有GMT时间、UTC时间等一堆概念堆上来的时候,总是心理发虚,招架不住。
YourBatman
2022/03/08
4.1K0
GMT UTC CST ISO 夏令时 时间戳,都是些什么鬼?
Python 的时间和时区
时间是一个绝对值,不论身处哪里都是一样的,比如Unix时间戳,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
YaoQi
2025/07/14
1720
Python 的时间和时区
ISO-8601 如何解读
如下: 1970-01-01T00:00:00Z 可能是我们最常看到的格式了,这个表示的是一个 Epoch 时间,其实也不完全一定是,因为在上面没有表示出毫秒。
HoneyMoose
2021/08/14
1K0
ISO-8601 如何解读
ISO8601时间字符串到时间戳处理
作者:matrix 被围观: 8,903 次 发布时间:2019-06-21 分类:Python 兼容并蓄 | 无评论 »
HHTjim 部落格
2022/09/26
1.9K0
Java日期问题汇总
通常格式化日期时,都是使用的YYYY/MM/dd来格式化日期,但是在遇到跨年日期时,就会遇到很神奇的现象,如下:
雨临Lewis
2022/01/12
1.7K0
Linux时间戳转换_时间戳转换软件
在大多数 UNIX 系统中,当前时间存储为自特定时刻以来经过的时间以简化,将时间保持为长整数。所有 UNIX 系统普遍接受的时刻是 1970 年 1 月 1 日凌晨 12:00:00。 这称为 UNIX 时间戳,并被所有现代 UNIX/Linux 系统识别。
全栈程序员站长
2022/11/09
17.6K0
Linux时间戳转换_时间戳转换软件
JSR310新日期API(一)-时区与时间偏移量
最近刚好有新项目使用到JSR-310(JDK8)中引入的新日期API,打算做一下总结。本文编写基于JDK11,部分API可能是JDK9之后新增的。
Throwable
2020/06/23
2K0
生信服务器 | Linux 时间戳和标准时间
在 Linux 系统中,有许多场合都使用时间戳的方式表示时间,即从1970年1月1日起至当前的天数或秒数。如/etc/shadow里的密码更改日期和失效日期,还有代理服务器的访问日志对访问时间的记录等等。
章鱼猫先生
2021/10/15
3.1K0
生信服务器 | Linux 时间戳和标准时间
超全!Python 处理日期与时间的全面总结!
https://www.biaodianfu.com/python-datetime.html
小F
2021/10/08
2.9K0
Js中Date对象
JavaScript的Date对象是用于处理日期和时间的全局对象,Date对象基于Unix Time Stamp,即自1970年1月1日UTC起经过的毫秒数。
WindRunnerMax
2020/10/26
22.2K0
推荐阅读
相关推荐
UTC时间戳与北京时间转换
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档