2016-04-22 201 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購買了亞馬遜的實例。 –

相關問題