PHP Carbon, get all dates between date range?

How can I get all dates between two dates in PHP? Prefer using Carbon for dates.

$from = Carbon::now();
$to = Carbon::createFromDate(2017, 5, 21);

I wanna have all dates between those two dates.. But how? Can only found solutions using strtotime function.


As of Carbon 1.29 it is possible to do:

$period = CarbonPeriod::create('2018-06-14', '2018-06-20');

// Iterate over the period
foreach ($period as $date) {
    echo $date->format('Y-m-d');
}

// Convert the period to an array of dates
$dates = $period->toArray();

See documentation for more details: https://carbon.nesbot.com/docs/#api-period.


Here's how I did it with Carbon

private function generateDateRange(Carbon $start_date, Carbon $end_date)
{
    $dates = [];

    for($date = $start_date->copy(); $date->lte($end_date); $date->addDay()) {
        $dates[] = $date->format('Y-m-d');
    }

    return $dates;
}

As Carbon is an extension of PHP's built-in DateTime, you should be able to use DatePeriod and DateInterval, exactly as you would with a DateTime object

$interval = new DateInterval('P1D');
$to->add($interval);
$daterange = new DatePeriod($from, $interval ,$to);

foreach($daterange as $date){
    echo $date->format("Ymd"), PHP_EOL;
}

EDIT

If you need to include the final date of the period, then you need to modify it slightly, and adjust $to before generating the DatePeriod

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($from, $interval ,$to);

foreach($daterange as $date){
    echo $date->format("Ymd"), PHP_EOL;
}

Based on Mark Baker's answer, I wrote this function:

/**
 * Compute a range between two dates, and generate
 * a plain array of Carbon objects of each day in it.
 *
 * @param  \Carbon\Carbon  $from
 * @param  \Carbon\Carbon  $to
 * @param  bool  $inclusive
 * @return array|null
 *
 * @author Tristan Jahier
 */
function date_range(Carbon\Carbon $from, Carbon\Carbon $to, $inclusive = true)
{
    if ($from->gt($to)) {
        return null;
    }

    // Clone the date objects to avoid issues, then reset their time
    $from = $from->copy()->startOfDay();
    $to = $to->copy()->startOfDay();

    // Include the end date in the range
    if ($inclusive) {
        $to->addDay();
    }

    $step = Carbon\CarbonInterval::day();
    $period = new DatePeriod($from, $step, $to);

    // Convert the DatePeriod into a plain array of Carbon objects
    $range = [];

    foreach ($period as $day) {
        $range[] = new Carbon\Carbon($day);
    }

    return ! empty($range) ? $range : null;
}

Usage:

>>> date_range(Carbon::parse('2016-07-21'), Carbon::parse('2016-07-23'));
=> [
     Carbon\Carbon {#760
       +"date": "2016-07-21 00:00:00.000000",
       +"timezone_type": 3,
       +"timezone": "UTC",
     },
     Carbon\Carbon {#759
       +"date": "2016-07-22 00:00:00.000000",
       +"timezone_type": 3,
       +"timezone": "UTC",
     },
     Carbon\Carbon {#761
       +"date": "2016-07-23 00:00:00.000000",
       +"timezone_type": 3,
       +"timezone": "UTC",
     },
   ]

You can also pass a boolean (false) as third argument to exclude the end date.