Ich habe 2 Daten in PHP. Wie kann ich eine foreach-Schleife ausführen, um all diese Tage zu durchlaufen?


206

Ich beginne mit einem Date 2010-05-01und ende mit 2010-05-10. Wie kann ich all diese Daten in PHP durchlaufen?

Antworten:


534

Benötigt PHP5.3:

$begin = new DateTime('2010-05-01');
$end = new DateTime('2010-05-10');

$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);

foreach ($period as $dt) {
    echo $dt->format("l Y-m-d H:i:s\n");
}

Dies gibt alle Tage im definierten Zeitraum zwischen $startund aus $end. Wenn Sie den 10. einschließen möchten, setzen Sie ihn $endauf den 11. Platz. Sie können das Format nach Ihren Wünschen anpassen. Siehe PHP-Handbuch für DatePeriod .


2
Gute Nachrichten - Es gibt einen Patch zum Setzen eines Flags mit dem Enddatum, das (Daumen drücken) in eine zukünftige Version aufgenommen wird.
salathe

8
$begin->setTime(0,0); $end->setTime(12,0);oder das Initialisieren mit der Uhrzeit des Startdatums, da jede Zeit nach dem Enddatum das Enddatum in die Schleife einschließt. Nicht die eleganteste Lösung, aber die beste Option, solange es keine richtige Flagge gibt.
Chris

31
Wenn Sie das Enddatum in Ihr Intervall aufnehmen möchten, haben Sie folgende Möglichkeiten: $ end = $ end-> modify ('+1 Tag');
JulienITARD

3
Ist es möglich, dies zu verwenden, aber umzukehren, um in die Geschichte zurückzukehren?
Jon

3
@ JulienITARD das ist eine ziemlich gute Idee, aber eleganter wäre $ end-> add ($ interval), weil es direkt auf ein geändertes Intervall reagiert;)
GDY

91

Dies beinhaltet auch das letzte Datum

$begin = new DateTime( "2015-07-03" );
$end   = new DateTime( "2015-07-09" );

for($i = $begin; $i <= $end; $i->modify('+1 day')){
    echo $i->format("Y-m-d");
}

Wenn Sie das letzte Datum nicht benötigen, entfernen Sie es einfach =aus dem Zustand.


1
Beachten Sie, dass $begindies nach der Schleife anders sein wird. Diese Schleife ändert das von erstellte Objekt new DateTime( "2015-07-03" ). Daher sollten Sie die DateTimeImmutable-Versionen verwenden. Sie benötigen jedoch einige weitere Modifikationen, um sie zu verwenden.
Henk Poley

39

Das Konvertieren in Unix-Zeitstempel erleichtert die Datumsberechnung in PHP:

$startTime = strtotime( '2010-05-01 12:00' );
$endTime = strtotime( '2010-05-10 12:00' );

// Loop between timestamps, 24 hours at a time
for ( $i = $startTime; $i <= $endTime; $i = $i + 86400 ) {
  $thisDate = date( 'Y-m-d', $i ); // 2010-05-01, 2010-05-02, etc
}

Wenn Sie PHP mit einer Zeitzone mit Sommerzeit verwenden, müssen Sie eine Zeit hinzufügen, die nicht 23:00, 00:00 oder 1:00 ist, um sich vor Tagen zu schützen, die übersprungen oder wiederholt werden.


4
Ich mag das Aussehen dieses 86400 nicht. Ich verstehe, dass es 60 * 60 * 24 ist, aber trotzdem ... ärgert mich etwas daran.
MikeD

13
In diesem Fall funktioniert es, aber wenn zwischen normaler und Sonnenlichtzeit
umgeschaltet wird, schlägt

2
Mike, das Beste ist, eine Konstante einzurichten und sie "TAG" zu nennen, damit sie viel einfacher zu lesen ist.
Der Pixel-Entwickler

5
Dies wird unter Sommerzeitproblemen leiden. Wenn Sie einen Sommerzeitpunkt überschreiten, wird es vermasselt. 12:00 Uhr ist nicht 12:00 Uhr auf beiden Seiten des Zeitpunkts.
Eric Cope

1
Dieser Code hat (jeder Code mit 86400 Sekunden pro Tag) Probleme mit der Sommerzeit! Bei Sommerzeit dauern einige Tage nur 23 Stunden und einige 25 Stunden.
sbrbot

19

Kopie von php.net Beispiel für inklusive Bereich:

$begin = new DateTime( '2012-08-01' );
$end = new DateTime( '2012-08-31' );
$end = $end->modify( '+1 day' ); 

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);

foreach($daterange as $date){
    echo $date->format("Ymd") . "<br>";
}

Dies ist die beste und vollständigste Antwort. Es fehlt nur eine Erklärung des DateInterval-Werts P1D. Hier einige Beispiele für den Periodenbezeichner. Zwei Tage: P2D Zwei Sekunden: PT2S Eine Woche und zehn Minuten: P1WT10M Y für Jahre M für Monate D für Tage W für Wochen. Diese werden in Tage umgewandelt und können daher nicht mit D. H für Stunden M für Minuten S für Sekunden
kombiniert werden

15
$startTime = strtotime('2010-05-01'); 
$endTime = strtotime('2010-05-10'); 

// Loop between timestamps, 1 day at a time 
$i = 1;
do {
   $newTime = strtotime('+'.$i++.' days',$startTime); 
   echo $newTime;
} while ($newTime < $endTime);

oder

$startTime = strtotime('2010-05-01'); 
$endTime = strtotime('2010-05-10'); 

// Loop between timestamps, 1 day at a time 
do {
   $startTime = strtotime('+1 day',$startTime); 
   echo $startTime;
} while ($startTime < $endTime);

2
Es scheint, dass diese Lösung langsamer ist als die akzeptierte Antwort (einige Bänke wurden nicht ausgeführt: 100% langsamer für 60 Iterationen). Aber ich wähle dieses für Retro-Kompatibilität für alte Hosting-Plattenformen.
Ifnot

7

Hier ist noch eine einfache -

/**
 * Date range
 *
 * @param $first
 * @param $last
 * @param string $step
 * @param string $format
 * @return array
 */
function dateRange( $first, $last, $step = '+1 day', $format = 'Y-m-d' ) {
    $dates = [];
    $current = strtotime( $first );
    $last = strtotime( $last );

    while( $current <= $last ) {

        $dates[] = date( $format, $current );
        $current = strtotime( $step, $current );
    }

    return $dates;
}

Beispiel:

print_r( dateRange( '2010-07-26', '2010-08-05') );

Array (
    [0] => 2010-07-26
    [1] => 2010-07-27
    [2] => 2010-07-28
    [3] => 2010-07-29
    [4] => 2010-07-30
    [5] => 2010-07-31
    [6] => 2010-08-01
    [7] => 2010-08-02
    [8] => 2010-08-03
    [9] => 2010-08-04
    [10] => 2010-08-05
)

5

Benutzer diese Funktion: -

function dateRange($first, $last, $step = '+1 day', $format = 'Y-m-d' ) {
                $dates = array();
                $current = strtotime($first);
                $last = strtotime($last);

                while( $current <= $last ) {    
                    $dates[] = date($format, $current);
                    $current = strtotime($step, $current);
                }
                return $dates;
        }

Nutzungs- / Funktionsaufruf: -

Erhöhung um einen Tag: -

dateRange($start, $end); //increment is set to 1 day.

Erhöhung um Monat: -

dateRange($start, $end, "+1 month");//increase by one month

Verwenden Sie den dritten Parameter, wenn Sie das Datumsformat einstellen möchten: -

   dateRange($start, $end, "+1 month", "Y-m-d H:i:s");//increase by one month and format is mysql datetime

2

Hier ist ein Weg:

 $date = new Carbon();
 $dtStart = $date->startOfMonth();
 $dtEnd = $dtStart->copy()->endOfMonth();

 $weekendsInMoth = [];
 while ($dtStart->diffInDays($dtEnd)) {

     if($dtStart->isWeekend()) {
            $weekendsInMoth[] = $dtStart->copy();
     }

     $dtStart->addDay();
 }

Das Ergebnis von $ weeksInMoth ist eine Reihe von Wochenendtagen!


0
$date = new DateTime($_POST['date']);
$endDate = date_add(new DateTime($_POST['date']),date_interval_create_from_date_string("7 days"));

while ($date <= $endDate) {
    print date_format($date,'d-m-Y')." AND END DATE IS : ".date_format($endDate,'d-m-Y')."\n";
    date_add($date,date_interval_create_from_date_string("1 days"));
}

Sie können auch so iterieren. Das $_POST['date']kann von Ihrer App oder Website $_POST['date']verbeult werden "21-12-2019". Stattdessen können Sie hier auch Ihre Zeichenfolge platzieren . Beides wird funktionieren.


0

Wenn Sie Laravel verwenden und Carbon verwenden möchten, ist die richtige Lösung die folgende:

$start_date = Carbon::createFromFormat('Y-m-d', '2020-01-01');
$end_date = Carbon::createFromFormat('Y-m-d', '2020-01-31');

$period = new CarbonPeriod($start_date, '1 day', $end_date);

foreach ($period as $dt) {
 echo $dt->format("l Y-m-d H:i:s\n");
}

Denken Sie daran, hinzuzufügen:

  • benutze Carbon \ Carbon;
  • benutze Carbon \ CarbonPeriod;

0
<?php

    $start_date = '2015-01-01';
    $end_date = '2015-06-30';

    while (strtotime($start_date) <= strtotime($end_date)) {
        echo "$start_daten";
        $start_date = date ("Y-m-d", strtotime("+1 days", strtotime($start_date)));
    }

?>
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.