Klaus: Mit PHP per Schleife durch Datumsbereich?

Hallo,

suche nach einer Möglichkeit mittels einer Schleife durch einen Datumsbereich zu laufen, um dann für jeden Tag eine Prüfung oder ähnliches durchführen zu können.

Dachte, dass es gaaanz einfach gehen könnte mittels:

$starttag = "08";
$startmonat = "10";
$startjahr = "2007";
$endetag = "25";
$endemonat = "10";
$endejahr = "2007";

$vdate = mktime(0,0,0,$startmonat,$starttag,$startjahr);
$bdate = mktime(0,0,0,$endemonat,$endetag,$endejahr);

for ($i = $vdate; $i < $bdate; $i++) {
 $test = date("Y-m-d",$i);
 echo $test."<br>";
}

Funktioniert aber leider gar nicht.

Gibts PHP-seitig überhaupt eine derartige Möglichkeit?

Gruß,

Klaus

  1. War vielleicht etwas vorschnell, denn ich hab eine akzeptable Lösung gefunden, die ich Euch natürlich nicht vorenthalten möchte:

    $starttag = "8";
    $startmonat = "10";
    $startjahr = "2007";
    $endetag = "25";
    $endemonat = "11";
    $endejahr = "2007";

    $vdate = mktime(0,0,0,$startmonat,$starttag,$startjahr);
    $bdate = mktime(0,0,0,$endemonat,$endetag,$endejahr);

    $tage = ($bdate-$vdate)/86400;

    for ($i = 0; $i < $tage; $i++) {
     $testdate = mktime(0,0,0,$startmonat,$starttag+$i,$startjahr);
     $test = date("Y-m-d",$testdate);
     echo "$i: $test<br>";
    }

    1. Hello,

      $tage = ($bdate-$vdate)/86400;

      Was ist mit Schaltjahr, was ist mit Zeitzonen, was ist mit Sommerzeit?

      Siehe hierzu auch den Thread
      https://forum.selfhtml.org/?t=160257&m=1042175

      Harzliche Grüße vom Berg
      http://bergpost.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

      1. Hallo Tom,

        $tage = ($bdate-$vdate)/86400;

        Was ist mit Schaltjahr, was ist mit Zeitzonen, was ist mit Sommerzeit?

        Nur Sommer- und Winterzeit sind bei der Methode ein Problem, Zeitzonen und Schaltjahre werden durch die PHP-Datumsfunktionen bereits berücksichtigt.

        Viele Grüße,
        Christian

        1. Hello,

          Nur Sommer- und Winterzeit sind bei der Methode ein Problem, Zeitzonen und Schaltjahre werden durch die PHP-Datumsfunktionen bereits berücksichtigt.

          Aber nicht bei der stumpfen Division

          $tage = ($bdate-$vdate)/86400;

          Es gibt Tage, die kürzer sind als 86400 Sekunden und
          es gibt Tage, die länger sind als 86400 Sekunden

          Harzliche Grüße vom Berg
          http://bergpost.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

          1. Hallo Tom,

            Nur Sommer- und Winterzeit sind bei der Methode ein Problem, Zeitzonen und Schaltjahre werden durch die PHP-Datumsfunktionen bereits berücksichtigt.

            Aber nicht bei der stumpfen Division

            $tage = ($bdate-$vdate)/86400;

            Es gibt Tage, die kürzer sind als 86400 Sekunden und
            es gibt Tage, die länger sind als 86400 Sekunden

            Sag ich ja: Sommer- und Winterzeit. Schaltjahre und Zeitzonen haben damit erstmal nicht allzu viel zu tun (wobei man Sommer- und Winterzeit immer zu den Zeitzonen zählt, aber ob ich nun bei UTC+02 oder UTC-11 eine Stunde addiere, ist egal).

            Viele Grüße,
            Christian

            1. Hello,

              Sag ich ja: Sommer- und Winterzeit. Schaltjahre und Zeitzonen haben damit erstmal nicht allzu viel zu tun (wobei man Sommer- und Winterzeit immer zu den Zeitzonen zählt, aber ob ich nun bei UTC+02 oder UTC-11 eine Stunde addiere, ist egal).

              Ok, das kann ich nachvollziehen.

              Aber die Gültigkeit der Mittelwertbildung über Unstetigkeitbereiche hinweg ist gerade mein Albtraum...

              Harzliche Grüße vom Berg
              http://bergpost.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau
              Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    2. Hallo,

      $starttag = "8";
      $startmonat = "10";
      $startjahr = "2007";
      $endetag = "25";
      $endemonat = "11";
      $endejahr = "2007";

      $vdate = mktime(0,0,0,$startmonat,$starttag,$startjahr);
      $bdate = mktime(0,0,0,$endemonat,$endetag,$endejahr);

      $tage = ($bdate-$vdate)/86400;

      for ($i = 0; $i < $tage; $i++) {
      $testdate = mktime(0,0,0,$startmonat,$starttag+$i,$startjahr);
      $test = date("Y-m-d",$testdate);
      echo "$i: $test<br>";
      }

      Der Code liefert Dir allerdings um die Zeitumstellungsgrenzen anderes Verhalten.

      1. Beispiel: Ohne Umstellung dazwischen:

      $starttag = "25";  
      $startmonat = "9";  
      $startjahr = "2007";  
      $endetag = "30";  
      $endemonat = "9";  
      $endejahr = "2007";
      

      Ergibt:

      0: 2007-09-25
      1: 2007-09-26
      2: 2007-09-27
      3: 2007-09-28
      4: 2007-09-29

      2. Beispiel: Mit Umstellung Sommer- auf Winter dazwischen:

      $starttag = "25";  
      $startmonat = "10";  
      $startjahr = "2007";  
      $endetag = "30";  
      $endemonat = "10";  
      $endejahr = "2007";
      

      Ergibt:

      0: 2007-10-25
      1: 2007-10-26
      2: 2007-10-27
      3: 2007-10-28
      4: 2007-10-29
      5: 2007-10-30

      3. Beispiel: Mit Umstellung Winter- auf Sommerzeit dazwischen:

      $starttag = "25";  
      $startmonat = "3";  
      $startjahr = "2008";  
      $endetag = "30";  
      $endemonat = "3";  
      $endejahr = "2008";
      

      Ergibt:

      0: 2008-03-25
      1: 2008-03-26
      2: 2008-03-27
      3: 2008-03-28
      4: 2008-03-29

      Im 2. Beispiel hast Du ein Datum mehr als in den anderen Fällen. Du kannst das Problem umgehen, indem Du round() durchführst:

      $tage = round (($bdate-$vdate)/86400);

      Dann funktioniert auch Deine Lösung in allen Fällen identisch.

      Viele Grüße,
      Christian

  2. Hallo Klaus,

    suche nach einer Möglichkeit mittels einer Schleife durch einen Datumsbereich zu laufen, um dann für jeden Tag eine Prüfung oder ähnliches durchführen zu können.

    Dachte, dass es gaaanz einfach gehen könnte mittels:

    [...]

    Funktioniert aber leider gar nicht.

    Naja, das funktioniert schon, nur nicht so, wie Du erwartet hast. Denn: mktime() liefert einen Timestamp und der ist Sekundengenau. Sprich: Wenn Du einen Tag addieren willst, dann musst Du eine größere Zahl pro Schleifendurchlauf addieren. Allerdings: Auf Grund von Sommer- und Winterzeit kann man nicht einfach 86400 Sekunden addieren (= 24 * 60 * 60), das fliegt auch auf die Schnauze, siehe auch ein analoges Problem in Python.

    Im folgenden zwei Möglichkeiten (die wurden auch in dem anderen Posting von mir angesprochen, siehe dort die Details zum Thema):

    1. (Weniger Empfehlenswert) Die Methode über "12 Uhr Mittags":
    $starttag = "08";  
    $startmonat = "10";  
    $startjahr = "2007";  
    $endetag = "25";  
    $endemonat = "11";  
    $endejahr = "2007";  
      
    $vdate = mktime(12,0,0,$startmonat,$starttag,$startjahr);  
    $bdate = mktime(12,0,0,$endemonat,$endetag,$endejahr);  
      
    // Sicherheitshalber +3600 rechnen, damit bei Sommer/Winterzeitumstellung  
    // Die Grenze korrekt erkannt wird - es ist bei dieser Methode auch nur  
    // möglich, *einschließlich* des Enddatums zu rechnen, *ausschließlich*  
    // (d.h. < statt <=) fliegt bei der umgekehrten Umstellung auf die Schnauze.  
    for ($i = $vdate; $i <= $bdate + 3600; $i += 86400) {  
     $test = date("Y-m-d",$i);  
     echo $test."<br>\n";  
    }
    
    1. (Meine Empfehlung) Die Methode über GMT (beachte das 'gm' vor den Funktionen):
    $starttag = "08";  
    $startmonat = "10";  
    $startjahr = "2007";  
    $endetag = "25";  
    $endemonat = "11";  
    $endejahr = "2007";  
      
    $vdate = gmmktime(0,0,0,$startmonat,$starttag,$startjahr);  
    $bdate = gmmktime(0,0,0,$endemonat,$endetag,$endejahr);  
      
    // Hier auch einschließlich (<=), obwohl hier ausschließlich (<) auch  
    // funktionieren würde.  
    for ($i = $vdate; $i <= $bdate; $i += 86400) {  
     $test = gmdate("Y-m-d",$i);  
     echo $test."\n";  
    }
    

    Die zweite Methode dürfte auch schneller sein und ist weniger fehleranfällig.

    Viele Grüße,
    Christian