我在考虑使用TIMESTAMP存储日期+时间,但我读到它有2038年的限制。我没有大量提出问题,而是倾向于将其分解成小部分,以便新手用户也能轻松理解。所以我的问题:
提前致谢。
答案 0 :(得分:123)
我已将此标记为社区维基,因此您可以随意编辑。
2038年1月19日星期二
DATE
列类型。如果您需要更高的准确度,请使用DATETIME
而不是TIMESTAMP
。请注意DATETIME
列不存储有关时区的信息,因此您的应用程序必须知道使用了哪个时区。尽可能尝试使用大型类型在数据库中存储日期:64位就足够了 - GNU C和POSIX / SuS中的long long类型,或PHP中的sprintf('%u'...)
或BCmath扩展名。
因此,MySQL DATETIME的范围为1000-9999,但TIMESTAMP的范围仅为1970-2038。如果您的系统存储了生日,未来的转发日期(例如30年抵押)或类似情况,那么您已经遇到了这个错误。同样,如果这是一个问题,请不要使用TIMESTAMP。
很少有PHP应用程序在2038年仍然存在,但很难预见因为网络还不是传统平台。
以下是更改数据库表列以将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`
<强>资源强>
答案 1 :(得分:12)
使用UNIX时间戳存储日期时,实际上使用的是32位整数,它保留自1970-01-01以来的秒数;见Unix Time
这个32位数字将在2038年溢出。这就是2038年的问题。
要解决该问题,您不能使用32位UNIX时间戳来存储日期 - 这意味着,在使用MySQL时,您不应使用TIMESTAMP
,而应使用DATETIME
(请参阅10.3.1. The DATETIME, DATE, and TIMESTAMP Types ):
当您使用
DATETIME
类型时 需要包含日期和值的值 时间信息。支持的范围 是'1000-01-01 00:00:00'
到'9999-12-31 23:59:59'
。
TIMESTAMP
数据类型有一个范围'1970-01-01 00:00:01'
UTC到'2038-01-19 03:14:07'
UTC。
您可以对应用程序执行的(可能)以避免/解决该问题的最佳方法是不使用TIMESTAMP
,而DATETIME
用于必须包含日期的列不是在1970年到2038年之间。
但是有一个小小的说明:有一个非常高的可能(从统计上讲)你的应用程序将在2038年之前被重写几次^^所以也许,如果你不喜欢将来不得不处理日期,您不必在当前版本的应用程序中处理该问题...
答案 2 :(得分:7)
快速搜索Google可以解决问题:Year 2038 problem
答案 3 :(得分:2)
http://en.wikipedia.org/wiki/Year_2038_problem包含大部分细节
总结:
1)+ 2)问题是许多系统将日期信息存储为32位有符号int,等于自1970年1月1日以来的秒数。可以像这样存储的最新日期是2038年1月19日星期二03:14:07 UTC。当发生这种情况时,int将“环绕”并存储为负数,这将被解释为1901年的日期。那么究竟会发生什么,因系统而异,但足以说它对任何一个都不好!
对于只存储过去日期的系统,我想你不需要担心一段时间!主要问题是将来使用日期的系统。如果您的系统需要使用未来28年的日期,那么您现在应该开始担心了!
3)使用可用的备用日期格式之一,或移至64位系统并使用64位整数。或者对于数据库使用替代时间戳格式(例如,对于MySQL使用DATETIME)
4)见3!
5)见4 !!! ;)
答案 4 :(得分:1)
Bros,如果您需要使用PHP来显示时间戳,这是最好的PHP解决方案,而不会改变UNIX_TIMESTAMP格式。
使用custom_date()函数。在其中,使用DateTime。 Here's the DateTime solution
只要你有UNSIGNED BIGINT(8)作为数据库中的时间戳。 只要你有PHP 5.2.0 ++
答案 5 :(得分:-1)
由于我不想升级任何东西,我让我的后端(MSSQL)代替PHP来完成这项工作!
$qry = "select DATEADD(month, 1, :date) next_date ";
$rs_tmp = $pdo->prepare($qry);
$rs_tmp->bindValue(":date", '2038/01/15');
$rs_tmp->execute();
$row_tmp = $rs_tmp->fetch(PDO::FETCH_ASSOC);
echo $row_tmp['next_date'];
可能不是一种有效的方法,但它有效。