PHP 和 Mysql 日期问题

最近在php 和 mysql上碰到了一个计算日期Bug:在mysql中使用date_add计算日期,比如date_add(now(),interval 30 year),然后保存进去的值就变成了’0000-00-00 00:00:00’;在php 中使用strtotime计算日期,比如(‘2143-08-22 15:23:56 -100 year’),然后格式化后就变成了’1970-01-01 ‘。后来google了下,发现这是著名的2038年问题
这个问题是因为在32位操作系统上日期类型是一个有正负号的32位整数,2147483647 是能表示的最大32为正整数,对应2038-01-19 03:14:07,超出了就“绕回”,所以不能正常处理。
怎么解决这个问题呢?使用64位的操作系统,这样子日期类型宽度就有64位了,能表示的日期就更大了。但是目前仍然有大量的程序运行在32为操作系统上,在php和mysql中要怎么处理呢?
在php中就不能使用strtotime来转换时间,因为它可能超出了。正确应该是用DateTime来处理时间。

$end=new DateTime('now');
$end->modify('20');
echo $end->format('Y-m-d');

$to=new DateTime('2100-08-22 21:40:00');
$interval=$end->diff($to);
echo $interval->format('%R%y 年');

在mysql中应该使用datetime来保存超过2038年的日期。timestamp和datetime的区别是:

datetime类型能够保存从1000-01-01 00:00:00至9999-12-31 23:59:59;timestamp只能保存从1970-01-01 00:00:01至2038-01-19 03:14:07。timestamp的保存范围小,在2038-01-19 03:14:07过后将会溢出,而datetime则不会。

timestamp是一个时间戳,能够使用CURRENT_TIMESTAMP来进行填充,而datetime则不行。

timestamp是跟时区相关的,在改变时区后,保存的值也会做相应的改变。而datetime保存的值是不会因为时区改变而改变。

所以如果要保存日期超过2038年的就选择datetime类型,如果是想在做update/inset是做一个自动日期记录而不关心日期的加减就选择timestamp。

参考链接
2038年问题
PHP & mySQL: Year 2038 Bug: What is it? How to solve it?
PHP Date and Time
PHP: strtotime is returning false for a future date?
Mysql DATE, DATETIME, and TIMESTAMP Types
Mysql时间字段格式如何选择,TIMESTAMP,DATETIME,INT?
Datetime vs Timestamp in MySQL and PHP in practice?

发表评论

电子邮件地址不会被公开。 必填项已用*标注