PHP 碳,得到所有日期之间的日期范围?

如何在 PHP 中获得两个日期之间的所有日期。

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

我想有这两个日期之间的所有日期. . 但如何? 只能找到解决方案使用 strtotime 函数。

122125 次浏览

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;
}

Here is what I have:

private function getDatesFromRange($date_time_from, $date_time_to)
{


// cut hours, because not getting last day when hours of time to is less than hours of time_from
// see while loop
$start = Carbon::createFromFormat('Y-m-d', substr($date_time_from, 0, 10));
$end = Carbon::createFromFormat('Y-m-d', substr($date_time_to, 0, 10));


$dates = [];


while ($start->lte($end)) {


$dates[] = $start->copy()->format('Y-m-d');


$start->addDay();
}


return $dates;
}

Example:

$this->getDatesFromRange('2015-03-15 10:10:10', '2015-03-19 09:10:10');

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;
}

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.

You can't use loop control variable directly, the next must be work fine

$start = Carbon::today()->startOfWeek();
$end = Carbon::today()->endOfWeek();


$stack = [];


$date = $start;
while ($date <= $end) {


if (! $date->isWeekend()) {
$stack[] = $date->copy();
}
$date->addDays(1);
}


return $stack;

This can also be done like this:

new DatePeriod($startDate, new DateInterval('P1D'), $endDate)

Just keep in mind that DatePeriod is an iterator, so if you want an actual array:

iterator_to_array(new DatePeriod($startDate, new DateInterval('P1D'), $endDate))

If you're using Laravel, you could always create a Carbon macro:

Carbon::macro('range', function ($start, $end) {
return new Collection(new DatePeriod($start, new DateInterval('P1D'), $end));
});

Now you can do this:

foreach (Carbon::range($start, $end) as $date) {
// ...
}

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.

You can directly using Carbon

    $start = Carbon::createFromDate(2017, 5, 21);
$end = Carbon::now();


while($start < $end){
echo $start->format("M");
$start->addMonth();
}
//To get just an array of dates, follow this.




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


$p = array();
// If you want just dates
// Iterate over the period and create push to array
foreach ($period as $date) {
$p[] = $date->format('Y-m-d');
}


// Return an array of dates


return $p;

Very simple solution (it works with old "<1.29" carbon ) :

// set $start and $end to any date
$start = Carbon::now()->addDays(-10);
$end = Carbon::now();


$dates = [];
for($i = 0; $i < $end->diffInDays($start); $i++){
$dates[] = (clone $start)->addDays($i)->format('Y-m-d');
}
dd($dates);

I think it's will be better if you use this function

 public static function check_continuous_dates(array $dates): bool
{
$startDate = Carbon::create($dates[0]);
$endDate = Carbon::create(end($dates));
if ($endDate->diffInDays($startDate)+1 == count($dates)) {
return true;
}
return false;
}