1

I am writing a calendar-based web application and am working on some code that will loop X amount of times and figure out the start/end dates & times of the future events. Each event has a start date/time and an end date/time The loop runs perfectly fine up until the year 2037, at which point the loop stop function properly. The conversion never takes place and reverts my dates back to 1969. Please see the code and output below. Can someone tell me why this is happening?

Live Example of Problem Behavior: http://codepad.org/h5ET3h2O

$date1 = strtotime('August 17 2011 8:00 AM');

for ($x=1; $x<=$repeatTimes; $x++){

    echo date('m/d/Y g:i A', $date1)."<br><br>".$date1 ." +". $repeatFreq." ".$repeatUnit. " = ";
    $date1 = strtotime(date('m/d/Y g:i A', $date1) . " +".$repeatFreq." ".$repeatUnit );
    echo $date1."<br /><br />";


}

Output

08/15/2011 8:00 AM
1313409600 +1 Year = 1345032000

08/15/2012 8:00 AM
1345032000 +1 Year = 1376568000

08/15/2013 8:00 AM
1376568000 +1 Year = 1408104000

//Some Left Out

08/15/2036 8:00 AM
2102414400 +1 Year = 2133950400

//Problem starts here

08/15/2037 8:00 AM
2133950400 +1 Year = 

12/31/1969 7:00 PM
+1 Year = 31536000

12/31/1970 7:00 PM
31536000 +1 Year = 63072000

12/31/1971 7:00 PM
63072000 +1 Year = 94694400

12/31/1972 7:00 PM
94694400 +1 Year = 126230400

12/31/1973 7:00 PM
126230400 +1 Year = 157766400

12/31/1974 7:00 PM
157766400 +1 Year = 189302400

//Some Left Out

UPDATE

I was able to utilize the DateTime Class to get the date working properly.

for ($x=1; $x<=$repeatTimes; $x++){
    $date1->modify(" +".$repeatFreq." ".$repeatUnit);
    $sDates[]=$date1->format('m/d/Y g:i A');
}
Dutchie432
  • 28,798
  • 20
  • 92
  • 109
  • 1
    Its the "Unix Millennium Bug" caused by a 32-bit integer rollover on the number of seconds since the Unix epoch: http://en.wikipedia.org/wiki/Year_2038_problem – James Aug 08 '11 at 16:16
  • Just out of interest, why do you need to calculate dates for that far in the future anyway? Wouldn't it make more sense to limit it to a sensible maximum number of years? – Steve Hill Aug 08 '11 at 16:20
  • Well, I am writing a business web app, and I am hoping that our business is still around in 26 years. Our web app should be able (in theory) to set anniversaries 26 years in advance as they occur every year. :) I'm not under the impression my app will still be in use that far ahead, but I'm sure that in the next 26 years, the data I am trying to produce will be migrated around from database to database for future technologies/apps. – Dutchie432 Aug 08 '11 at 16:25

1 Answers1

6

http://en.wikipedia.org/wiki/Unix_time

You're hitting the max value of a 32-bit integer.

Time is measured as the number of seconds since January 1, 1970 UTC. You see 1969 because in your timezone, that's when this would occur. When the number of seconds overflows the 32-bit int, it loops back around.

You can confirm the max integer value with this: echo PHP_INT_MAX;.

If you want 64-bit integers, you need to use 64-bit hardware, and a 64-bit version of PHP (which usually these days, you have to compile yourself, as I don't believe official binaries are available on PHP.net yet).

There are also other options. See here: how to have 64 bit integer on PHP?

Edit: Per Maerlyn's suggestion, you should consider using the DateTime class built into recent versions of PHP. It should get you around this problem, as long as you use it consistently.

Community
  • 1
  • 1
Brad
  • 159,648
  • 54
  • 349
  • 530
  • 2
    I'd also add the tip of using php's DateTime class, which works past 2038. – Maerlyn Aug 08 '11 at 16:18
  • Actually, while your answer was extremely well thought out and descriptive, Maerlyn's solution did the trick. Updated code above. – Dutchie432 Aug 08 '11 at 16:36