Wow. Just got hit with this bug. It’s going to be a fairly easy fix (more on that later), but crazy none the less.
Excerpt from wikipedia:
“The year 2038 problem may cause some computer software to fail at some point near the year 2038. The problem affects all software and systems that both store system time as a signed 32-bit integer, and interpret this number as the number of seconds since 00:00:00 UTC on Thursday, 1 January 1970. The furthest time that can be represented this way is 03:14:07 UTC on Tuesday, 19 January 2038. Times beyond this moment will “wrap around” and be stored internally as a negative number, which these systems will interpret as a date in 1901 rather than 2038. This is caused by integer overflow.”
I wrote a reporting system for a client of mine. It displays memberships based on their expiration date. Several members have their expiration dates set as 2046 and higher. I found that these members were being incorrectly classified by the system as expired. Hello Y2K bug all over again!
For MySQL, I found that storing dates as DATETIME rather than TIMESTAMP solves the issue. For PHP, using the DateTime API allows you to work with dates beyond 2038.
$date = new DateTime('9999-04-05'); echo '<br/>'.$date->format('Y-M-j') ."";
In my case, I was actually following this already by storing the dates in the database as DATETIME and using PHP’s DateTime API to process the dates. In my case the problem came into play when… I was comparing dates using strtotime():
$d1 = strtotime(date('Y/m/d')); $d2 = strtotime($expireDate); var_dump($d1 == $d2); var_dump($d1 > $d2); var_dump($d1 < $d2);
Switched to comparing the DateTime objects and problem solved:
$d1 = new DateTime('2046-08-03 14:52:10'); $d2 = new DateTime('2008-01-03 11:11:10'); var_dump($d1 == $d2); var_dump($d1 > $d2); var_dump($d1 < $d2);