PHP Carbon, alle Daten zwischen Datumsbereich erhalten?


72

Wie kann ich alle Daten zwischen zwei Daten in PHP abrufen? Verwenden Sie lieber Carbon für Datteln.

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

Ich möchte alle Daten zwischen diesen beiden Daten haben. Aber wie? Kann nur Lösungen mit der Funktion strtotime finden.

Antworten:


126

Ab Kohlenstoff 1.29 ist Folgendes möglich:

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

Weitere Informationen finden Sie in der Dokumentation: https://carbon.nesbot.com/docs/#api-period .


66

So habe ich es gemacht 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;
}

2
Wirst du nicht das Problem haben $start_date, $end_dateam Ende gleich zu sein ? Wenn Sie das Original $start_datenach dem Aufruf dieser Funktion weiter verwenden möchten , sollten Sie entweder eine Kopie des Originals $start_datean diese Funktion übergeben oder $date = $start_date -> copy()die Definition der forSchleife festlegen, die ich bevorzugen würde.
Molerat

19

Da Carbon eine Erweiterung von PHPs integriertem DateTime ist, sollten Sie DatePeriod und DateInterval genau wie bei einem DateTime-Objekt verwenden können

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

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

BEARBEITEN

Wenn Sie das Enddatum des Zeitraums $toangeben müssen, müssen Sie es geringfügig ändern und anpassen, bevor Sie den DatePeriod generieren

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

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

Das letzte Datum aus dem Intervall wird nicht gedruckt, wenn $ bis Zeit nicht größer ist. Ich meine, zumindest auf der zweiten muss größer sein, vielleicht eine Millisekunde, habe das nicht versucht
Dariux

Relevante Codezeile hinzugefügt, um das bisherige $ in den Zeitraum aufzunehmen
Mark Baker

11

Basierend auf Mark Bakers Antwort habe ich diese Funktion geschrieben:

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

Verwendung:

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

Sie können auch ein boolesches ( false) als drittes Argument übergeben, um das Enddatum auszuschließen.


5

Dies kann auch folgendermaßen erfolgen:

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

Denken Sie daran, dass dies DatePeriodein Iterator ist. Wenn Sie also ein tatsächliches Array möchten:

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

Wenn Sie Laravel verwenden, können Sie jederzeit ein Carbon-Makro erstellen:

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

Jetzt können Sie dies tun:

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

3

Folgendes habe ich:

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

Beispiel:

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

3

Sie können Carbon direkt verwenden

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

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

2

Sie können die Regelungsvariable nicht direkt verwenden, die nächste muss einwandfrei funktionieren

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

-1

Sehr einfache Lösung (funktioniert mit altem "<1,29" Kohlenstoff):

// 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);

Erstaunlich langsame Lösung
user1469734

Die schnellste Lösung ist natürlich mit CarbonPeriod, aber es ist eine relativ neue Caarbon-Funktion und viele Apps können das nicht verwenden. Meine Lösungen decken ältere Carbon-Versionen ab und sind genauso schnell wie die Lösung von @Sebastien ... Ich habe sie gerade gemessen ... ..
fico7489

-2
//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;

Bitte fügen Sie Ihrer Antwort eine Beschreibung hinzu, damit jeder verstehen kann, was Ihr Codealgorithmus ist. Nicht mit dem Löffel füttern.
FendiSetiawan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.