2016-04-22 157 views
2

select unix_timestamp('2038-01-19')回报2147472000年2038问题 - 64位(Linux操作系统,PHP和MySQL)

select unix_timestamp('2038-01-20')回报0

我已签了一年2038问题。

我的linux操作系统是64位,安装mysql版本也是64位。现在解决这个问题的方法是什么?

mysql --version返回mysql Ver 14.14 Distrib 5.5.47, for Linux (x86_64) using readline 5.1
Php也是64位。

也尝试过BigInt,没有工作(返回相同的东西)。

+0

'选择UNIX_TIMESTAMP(“2038年1月19日”)返回2147472000' '而选择UNIX_TIMESTAMP(“2038年1月19日”)返回0'你可以告诉正是在这两个查询区别? –

+0

@安南是一个错字..感谢 –

+0

然后在你的问题中改变它 –

回答

6

简单地说,对于MySQL,存储日期为DATETIME而不是TIMESTAMP

时间戳为4个字节,所以没有物理空间来存储更多秒比自1970-1-1到2038年1月19日...

DATETIME,相反,有一系列的1000-1 -1至9999-12-31 ...

参见本完整提问/回答:PHP & mySQL: Year 2038 Bug: What is it? How to solve it?

UPDATE: 一个可能替代我看,如果你不能改变你的字段类型,是interp等你不同的时间戳...
我的意思是:如果第一事件您的应用程序将跟踪的是 - 说 - 2000-1-1,你可以实现对后端的过滤器(或内部数据库中的存储过程) ,在阅读时添加(2000-1-1-1970-1-1)秒到您的时间戳,并在阅读时减去相同的数量...这应该会给您多30年的'生存'...

+0

我们在数据库中保留它作为INT,不想重新设计它。 –

+2

@DanyalSandeelo:我不想在下个月支付租金。我想我们都必须不高兴。 *耸耸肩* –

+0

@ IgnacioVazquez-Abrams该应用程序在UAT中。所有表格都以INT格式存储日期,我不能冒险截止日期。虽然我知道,日期时间将解决问题 –

3

MySQL文档通常非常模糊关于函数返回的数据类型,UNIX_TIMESTAMP()也不例外。除非我们检查源代码,否则我们只能做出有根据的猜测。

Date and Time Type Overview,我们可以读到,TIMESTAMP数据类型本身具有不依赖于服务器体系结构的记录范围:

范围为“1970-01-01 00:00:01.000000” UTC到 '2038-01-19 03:14:07.999999'UTC。 TIMESTAMP值存储为 自纪元('1970-01-01 00:00:00'UTC)以来的秒数。 A TIMESTAMP无法表示值'1970-01-01 00:00:00',因为 相当于从纪元0秒,值0是 保留代表'0000-00-00 00:00:00 ',“零”TIMESTAMP 值。

即使我们要确保我们通过一个适当的日期类型:

mysql> select 
    -> str_to_date('2038-01-20', '%Y-%m-%d'), 
    -> unix_timestamp(str_to_date('2038-01-20', '%Y-%m-%d')); 
+---------------------------------------+-------------------------------------------------------+ 
| str_to_date('2038-01-20', '%Y-%m-%d') | unix_timestamp(str_to_date('2038-01-20', '%Y-%m-%d')) | 
+---------------------------------------+-------------------------------------------------------+ 
| 2038-01-20       |              0 | 
+---------------------------------------+-------------------------------------------------------+ 
1 row in set (0.01 sec) 

...我们仍然得到0,错误愚蠢的功能标志:

如果您传递超出范围的日期UNIX_TIMESTAMP(),则返回0。

所以它是一种安全的假设UNIX_TIMESTAMP()返回的值为TIMESTAMP,因此不支持2038+。

简而言之:您必须计算其他地方(即您的客户端代码)的时间戳。由于有一个PHP标签:

$t = new DateTime('2038-01-20', new DateTimeZone('UTC')); 
var_dump($t->format('U')); 

串(10) “2147558400”


附: MariaDB的,MySQL的叉子,有相同的限制,但它documents it更好:

时间戳在MariaDB的有2147483647最大值,相当于 于2038年1月19日5时14分07秒。这是由于底层的32位 限制。使用超出此日期的函数将导致返回NULL 。

+0

2038-01-19返回的值与2147472000相同 –

+0

我们需要知道时区以及您在何处/如何计算该数字。你是指我的PHP代码片段? : - ? –

+0

我在mysql客户端执行这个sql查询。我已经用linux购买了亚马逊的实例。 –

相关问题