PHP Carbon, получить все даты между диапазоном дат?

Как я могу получить все даты между двумя датами в PHP? Предпочитаю использовать Carbon для фиников.

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

Я хочу иметь все даты между этими двумя датами.. Но как? Можно найти решения только с помощью функции strtotime.


person user1469734    schedule 06.08.2015    source источник


Ответы (11)


Начиная с Carbon 1.29 можно сделать:

$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();

Дополнительные сведения см. в документации: https://carbon.nesbot.com/docs/#api-period .

person Paul    schedule 14.06.2018

Вот как я это сделал с 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;
}
person Sebastian Sulinski    schedule 26.01.2016
comment
У вас не будет проблемы с тем, что $start_date в конце концов будет равно $end_date? Если вы хотите продолжать использовать исходный $start_date после вызова этой функции, вы должны либо передать копию исходного $start_date этой функции, либо установить $date = $start_date -> copy() в определении for-цикла, что я бы предпочел. - person molerat; 09.07.2018

Поскольку Carbon является расширением встроенного в PHP DateTime, вы должны иметь возможность использовать DatePeriod и DateInterval точно так же, как с объектом DateTime.

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

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

ИЗМЕНИТЬ

Если вам нужно включить конечную дату периода, вам нужно немного изменить ее и настроить $to перед созданием DatePeriod

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

foreach($daterange as $date){
    echo $date->format("Ymd"), PHP_EOL;
}
person Mark Baker    schedule 06.08.2015
comment
Это не печатает последнюю дату из интервала, если $to time не больше. Я имею в виду, по крайней мере, на секунду должно быть больше, может быть, миллисекунда, не пробовал - person Dariux; 10.09.2015
comment
Добавлена ​​соответствующая строка кода для включения даты $to в период - person Mark Baker; 10.09.2015

Основываясь на ответе Марка Бейкера, я написал эту функцию:

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

Использование:

>>> 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",
     },
   ]

Вы также можете передать логическое значение (false) в качестве третьего аргумента, чтобы исключить дату окончания.

person Tristan Jahier    schedule 22.07.2016

Это также можно сделать так:

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

Просто имейте в виду, что DatePeriod — это итератор, поэтому, если вам нужен фактический массив:

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

Если вы используете Laravel, вы всегда можете создать макрос Carbon:

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

Теперь вы можете сделать это:

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

Вот что у меня есть:

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

Пример:

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

Вы можете напрямую использовать Carbon

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

    while($start < $end){
        echo $start->format("M");
        $start->addMonth();
    }
person latecoder    schedule 01.10.2018

Вы не можете напрямую использовать переменную управления циклом, следующая должна работать нормально

$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;
person marcelo gutierrez    schedule 16.10.2017

Очень простое решение (работает со старым углеродом "‹1.29"):

// 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);
person fico7489    schedule 01.05.2020
comment
Удивительно медленное решение - person user1469734; 02.05.2020
comment
самое быстрое решение, очевидно, с CarbonPeriod, но это относительно новая функция Caarbon, и многие приложения не могут ее использовать, мои решения охватывают более старую углеродную версию и такие же быстрые, как решение от @Sebastien ... Я только что измерил это .... .. - person fico7489; 02.05.2020

В этом руководстве будет представлен пример получения углерода laravel за все месяцы между двумя датами. шаг за шагом объяснить laravel углерода получить все месяцы. Этот пост даст вам простой пример получения углерода за все месяцы между датами. Мы будем использовать laravel carbon для получения всех месяцев между двумя датами. Здесь создаем базовый пример получения месяцев между двумя датами laravel.

  
namespace App\Http\Controllers;
  
use Carbon\Carbon;
use Carbon\CarbonPeriod;
  
class SignaturePadController extends Controller
{
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function index()
    {
        $result = CarbonPeriod::create('2020-01-01', '2020-12-01');
  
        foreach ($result as $dt) {
            echo $dt->format("Y-m");
        }
       $dates = $result->toArray();
    }
}

Источник: https://www.itsolutionstuff.com/post/laravel-carbon-get-all-months-between-two-dates-exampleexample.html

person whitehawk    schedule 06.05.2021

person    schedule
comment
Пожалуйста, добавьте описание к своему ответу, чтобы любой мог понять, каков ваш алгоритм кода. Не кормите с ложки. - person ibnǝꟻ; 30.01.2020