0

I need to generate a list of dates (with either php or mysql or both) where i have a start and end date specified? For example if the start date is 2012-03-31 and the end date is 2012-04-05 how can i generate a list like this?

2012-03-31
2012-04-01
2012-04-02
2012-04-03
2012-04-04
2012-04-05

I have a mysql table with a start and end date but i need the full list of dates.

1
  • what is a format of your DB timestamp? Commented Mar 31, 2012 at 15:32

4 Answers 4

1

Something like this should do it:

//Get start date and end date from database

$start_time = strtotime($start_date);
$end_time = strtotime($end_date);
$date_list = array($start_date);

$current_time = $start_time;

while($current_time < $end_time) {
    //Add one day
    $current_time += 86400;
    $date_list[] = date('Y-m-d',$current_time);
}
//Finally add end date to list, array contains all dates in order
$date_list[] = $end_date;

Basically, convert the dates to timestamps and add a day on each loop.

Sign up to request clarification or add additional context in comments.

Comments

1

Using PHP's DateTime library:

<?php

$start_str = '2012-03-31';
$end_str = '2012-04-05';

$start = new DateTime($start_str);
$end = new DateTime($end_str . ' +1 day'); // note that the end date is excluded from a DatePeriod

foreach (new DatePeriod($start, new DateInterval('P1D'), $end) as $day) {
        echo $day->format('Y-m-d'), "\n";
}

Source

Comments

0

Try this:

<?php

  // Set the start and current date
  $start = $date = '2012-03-31';

  // Set the end date
  $end = '2012-04-05';

  // Set the initial increment value
  $i = 0;

  // The array to store the dates
  $dates = array();

  // While the current date is not the end, and while the start is not later than the end, add the next day to the array    
  while ($date != $end && $start <= $end)
  {
    $dates[] = $date = date('Y-m-d', strtotime($start . ' + ' . $i++ . ' day'));
  }

  // Output the list of dates
  print_r($dates);

Comments

0

Super fast version

Date conversions are costly. I was disappointed by the performance so I tried to tune it a little for speed. It's more like a case study for optimization, but I'm going to leave it here because it's almost 3x faster than usual. It works by reducing the number of times date( ) being called.

function listDaysBetween($from,$till) {

    if($till<$from) return[];            //  handle the obvious empty case

    $tsFrom = strtotime("$from 11:00");  //  middle of first day
    $tsTill = strtotime("$till 11:00");  //  middle of last day
    $tsDiff = $tsTill - $tsFrom;         //  seconds diff
    $diff = round($tsDiff/86400);        //  days diff; output length
    $ts = $tsFrom;                       //  $ts will follow us along
    $day = $from;                        //  $day will scan the range
    $days = [$day];                      //  put the first one in there

    while($diff-->0) {                   //  a disguised for-loop
        $ts+=86400;                      //  keep timestamp following
        $d = (int)($day[8].$day[9]);     //  get the day part (fast)

        if($d>27) {                      //  at the end of each month,
            $day = date("Y-m-d",$ts);    //  it's better to ask date()
        }else{                           //  otherwise we do it faster
            $d+=101; $d="$d";            //  zero-padding to 2 digits
            $day[8] = $d[1];             //  direct character replace
            $day[9] = $d[2];             //  is faster than substr()
        }
        $days[] = $day;                  //  build output array
    }

    return $days;
}

I hope you'll enjoy the nasty tricks. Tried many ways for many parts of this code, this version is a clear winner so far but I'm open for suggestions. (Apart from caching in a static variable for subsequent calls. That's cheating. I'd totally do it but still.)

Read more about this if you like.

NOTE: this function has no input control, you'll need at least some regex to avoid accidental endless loops when calling with bogus data. I omitted those lines for brevity.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.