我想用时间戳来存储日期+时间,但我读到它有2038年的限制.我宁愿把问题分成几个小部分,以便新手也能轻松理解,而不是大量提问.所以我的问题是:

  1. 2038年的问题到底是什么?
  2. 它为什么会发生,当它发生时会发生什么?
  3. 我们如何解决它?
  4. 除了使用它,还有没有其他不构成类似问题的替代方案?
  5. 当所谓的问题真的发生时,我们可以对使用时间戳的现有应用程序做些什么来避免它呢?

提前谢谢.

推荐答案

I have marked this as a community wiki so feel free to edit at your leisure.

2038年的问题到底是什么?

"2038年的问题(也被称为Unix千年虫,与Y2K问题类似的Y2K38)可能导致某些计算机软件在2038年之前或之后出现故障.该问题影响所有将系统时间存储为有符号32位整数的软件和系统,并将该数字解释为自1970年1月1日UTC 00:00:00以来的秒数."


为什么会发生,发生时会发生什么?

超过03:14:07 UTC on Tuesday, 19 January 2038的时间将"环绕",并在内部存储为负数,这些系统会将其解释为1901年12月13日的时间,而不是2038年的时间.这是因为自UNIX纪元(1970年1月1日00:00:00 GMT)以来的秒数将超过计算机对32位有符号整数的最大值.


我们如何解决它?

  • 使用LONG数据类型(64位就足够了)
  • 对于MySQL(或MariaDB),如果不需要时间信息,可以考虑使用DATE列类型.如果你需要更高的准确度,使用DATETIME而不是TIMESTAMP.请注意,DATETIME列不存储有关时区的信息,因此应用程序必须知道使用了哪个时区.
  • Other Possible solutions described on Wikipedia
  • 等待MySQL开发人员修复十多年前报告的this bug个.

除了使用它,还有没有其他不构成类似问题的替代方案?

尽可能try 使用大型类型在数据库中存储日期:64位就足够了-GNU C和POSIX/sus中的long long类型,或者PHP或BCath扩展中的sprintf('%u'...).


即使我们还没有到2038年,有哪些潜在的突破性用例?

因此,MySQLDATETIME的范围是DATETIME0-9999,但是时间戳的范围只有1970-2038.如果您的系统存储了出生日期、future 远期日期(例如30年抵押贷款)或类似日期,那么您就已经遇到这个错误了.同样,如果这将是一个问题,请不要使用时间戳.


我们可以对使用时间戳的现有应用程序做些什么来避免所谓的问题,当它真正发生时?

2038年,几乎没有PHP应用程序仍然存在,尽管很难预见,因为web还很难成为遗留平台.

下面是更改数据库表列以将TIMESTAMP转换为DATETIME的过程.首先创建一个临时列:

# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;

# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;

# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);

# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`

Resources

Php相关问答推荐

ngnix php8.0-fPM主要脚本未知

带有打印和回声的PHP意外命令

未找到laravel cascadeOnEdit

composer如何解析包名?

保存PHP条带以备将来使用,不显示用户界面

Laravel数据表在一个视图中传递两个实例

从WC会话变量更改WooCommerce checkout 托运方法成本

Php解压缩deflate64

通过访问单个产品页面更新WooCommerce产品元数据

当配置的URL为空时禁用Laravel Slack日志(log)记录

使用CODIGNITER3中的OR和AND子句进行查询

PHP SimpleXML:按属性值访问 node

shell_exec运行大型数据处理

Azure应用程序无法访问共享文件夹

Laravel withOnly不限制查询

用自定义代码替换 WooCommerce 单一产品简短描述

如何判断php中wordpress路径之外的文件夹是否存在?

woocommerce checkout 页面上的自定义字段

Laravel 模型将日期保存为空

获取具有所有特定相关模型的模型