fnairb Posted February 22, 2008 Share Posted February 22, 2008 So here is my challenge. I need to load an array with date strings. That is, given a start date, end date, and frequency spit out an array of person friendly date strings. I have used epoc with some success (See Attempt 1) and strtotime() works just fine (See: Attempt 2). However, it is just too slow. There has to be a better way to do this. Attempt 1: Use Epoc The fillEpoc() function defined below just loops through a range of epocs incrementing by the given frequency. It worked great for quite a while but then there is a nasty little shift in time. $filled = fillEpoc('2007-10-21', '2008-01-21', 86400); print_r($filled); With an output of: (notice the unexpected shift at [14]) Array ( \[0] => 2007-10-21 00:00 [1] => 2007-10-22 00:00 ... [14] => 2007-11-04 00:00 [15] => 2007-11-04 23:00 [16] => 2007-11-05 23:00 ... ) Attempt 2: use strtotime() The fillStrToTime() function works as expected. However, it really seems to be overkill. With large date ranges or small frequencies it takes too long to complete for comfort. Sample Code: function fillEpoc ($startDate, $endDate, $frequency) { $dates = array(); $startEpoc = strtotime($startDate); $endEpoc = strtotime($endDate); for($i = $startEpoc; $i <= $endEpoc; $i += $frequency){ $dates[] = date('Y-m-d H:i', $i); } return $dates; } function fillStrToTime($startDate, $endDate, $frequency) { $dates = array(); $startEpoc = strtotime($startDate); $endEpoc = strtotime($endDate); $steps = ($endEpoc - $startEpoc) / $frequency; switch(frequency) { case 86400: $step = 1; $step_unit = ' days'; break; case 3600: $step = 1; $step_unit = ' hours'; break; case 300: $step = 5; $step_unit = ' minutes'; break; default: $step = $frequency; $step_unit = ' seconds'; } for($i = 0; $i <= $steps; $i++){ $e = strtotime(($i * $step) . $step_unit, $startEpoc); $dates[] = date('Y-m-d H:i', $e); } return $dates; } Quote Link to comment Share on other sites More sharing options...
Psycho Posted February 22, 2008 Share Posted February 22, 2008 Your first function is working correctly. That "shift" is due to daylight savings time adjustment. Quote Link to comment Share on other sites More sharing options...
fnairb Posted February 25, 2008 Author Share Posted February 25, 2008 The results are accurate but not what I am looking for. The goal in this particular example is to generate a series of labels not to generate a series of accurate date representations. So while the inclusion of daylight savings time is accurate it is not helping me generate the desired output. Quote Link to comment Share on other sites More sharing options...
Psycho Posted February 25, 2008 Share Posted February 25, 2008 Personally I would changethe function to use something other than seconds, but since you didn't specify what flexibility it needed I didn't change that. <?php function fillEpoc($startDate, $endDate, $frequency) { $dates = array(); $startEpoc = strtotime($startDate); $endEpoc = strtotime($endDate); $newdateEpoc = $startEpoc; $year = date('Y', $startEpoc); $month = date('m', $startEpoc); $day = date('d', $startEpoc); $hours = date('H', $startEpoc); $minutes = date('i', $startEpoc); $seconds = date('s', $startEpoc); while($newdateEpoc <= $endEpoc){ $dates[] = date('Y-m-d H:i:s', $newdateEpoc); $seconds = $seconds + $frequency; $newdateEpoc = mktime($hours, $minutes, $seconds, $month, $day, $year); } return $dates; } ?> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.