我想用时间戳来存储日期+时间,但我读到它有2038年的限制.我宁愿把问题分成几个小部分,以便新手也能轻松理解,而不是大量提问.所以我的问题是:
- 2038年的问题到底是什么?
- 它为什么会发生,当它发生时会发生什么?
- 我们如何解决它?
- 除了使用它,还有没有其他不构成类似问题的替代方案?
- 当所谓的问题真的发生时,我们可以对使用时间戳的现有应用程序做些什么来避免它呢?
提前谢谢.
我想用时间戳来存储日期+时间,但我读到它有2038年的限制.我宁愿把问题分成几个小部分,以便新手也能轻松理解,而不是大量提问.所以我的问题是:
提前谢谢.
I have marked this as a community wiki so feel free to edit at your leisure.
"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位有符号整数的最大值.
DATE
列类型.如果你需要更高的准确度,使用DATETIME
而不是TIMESTAMP
.请注意,DATETIME
列不存储有关时区的信息,因此应用程序必须知道使用了哪个时区.尽可能try 使用大型类型在数据库中存储日期:64位就足够了-GNU C和POSIX/sus中的long long类型,或者PHP或BCath扩展中的sprintf('%u'...)
.
因此,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