Achot: Datum richtig speichern

Hallo,

irgendwie stehe ich gerade total auf dem Schlauch. Folgendes Insert

if(isset($_POST['abschicken'])){

  if ($stmt = $mysqli->prepare("INSERT INTO zeitraum (artikelID, datum, status) VALUES (?, ?, ?)"))
     
     { 
     
      $artikelID	= $artikel;
      $datum   		= "";
      $status       	= "1";  
         
      $stmt->bind_param("sss", $artikelID, $datum, $status);
      
      $stmt->execute();
     
      }

      else {
        echo $mysqli -> error;
      }

  }

Jetzt kommt mein Problem. Der User wählt ein Datum, dieses steht in

$von
$bis

Das Datum könnte folgendermaßen lauten: 20.02.2017 - 25.02.2017 oder 20.02.2017 - 20.02.2017 oder 15.02.2017 - 28.09.2017

Ich möchte jetzt für jeden Tag ein eigenen Eintrag haben, da ich das Datum später in einem Kalender ausgeben lassen möchte.

Wie baue ich da jetzt eine schleife auf?

akzeptierte Antworten

  1. Ich möchte jetzt für jeden Tag ein eigenen Eintrag haben, da ich das Datum später in einem Kalender ausgeben lassen möchte.

    Meine Empfehlung: Speichere den Termin nur einmal in der Datenbank und erstelle die Kopien bei der Ausgabe.

    Grund: Wenn sich was ändert (15.02.2017 - 28.09.2017) musst du wieviel hundert Datensätze ändern?

    Wie baue ich da jetzt eine schleife auf?

    Erstelle für den Start-Termin einen Unix-Timestamp mittags. Von Tag zu Tag addierst du die Tages-Sekunden 60*60*24 und wandelst die wieder zum Datum. Dann hast du keinen Stress mit Schaltjahren. Und bei Sommer/Winter Umstellung ist es täglich noch das richtige Datum.

    Nach Erreichen des letzten Tages beendest du die Schleife.

    Lang laufende Veranstaltungen haben gerne Ruhetage. Also Vorsicht bei dieser pauschalen Automatik.

    1. Hallo,

      ich glaube, ich habe mich nicht richtig ausgedrückt. Es geht mir nicht um den Termin, der steht schon allein in einer Tabelle. Es geht mir um das Zeug, was man dazu buchen kann wie z.B. ein Eintrag auf der Startseite. Der User kann ein Datum wählen von wann bis wann die Anzeige auf der Startseite bzw. auf einer beliebigen Seite angezeigt werden soll und diesen Wert muss ich getrennt vom Artikel in einer separaten Tabelle speichern.

      Achso, auf die Uhrzeit kommt es mir nicht an, es sind immer ganze Tage.

      1. Liebe(r) Achot,

        dann brauchst Du eben eine Spalte "begin" und eine Spalte "end" mit einem DATE-Wert (YYYY-MM-DD).

        Liebe Grüße,

        Felix Riesterer.

        1. Guten Morgen,

          es geht mir um folgendes

          // 22.2.2017
          $von
          // 24.05.2017
          $bis
          

          Ich möchte jeden Tag in eine eigene Zeile speichern. Dafür benötige ich eine schleife, dass ich bei jedem Durchlauf ein INSERT machen kann. Die Frage ist, wie lautet die Schleife?

          1. Hallo Achot,

            am besten ist wahrscheinlich, wenn Du über DatePeriod iterierst.

            Dazu musst Du zuerst aus Deinem Von und Bis DateTime-Objekte erzeugen. Zusätzlich benötigst Du ein DateInterval mit der Spezifikation "P1D". Das entspricht einem Tag. In den Kommentaren bei DatePeriod in der Spec findest Du ein Beispiel. Als Schleife verwendest Du anschließend foreach.

            Der Vorteil von DatePeriod ist, dass Du Dir keine Gedanken über Monatswechsel, Schaltjahre, etc. machen musst.

            Gruß
            Dennis

            1. Hallo,

              Als Schleife verwendest Du anschließend foreach.

              Mit datePeriod habe ich keine Erfahrung, ist damit wirklich foreach sinnvoll?
              Wenn man bereits die Anzahl der Tage hat, böte sich eine einfache For-Schleife an. Natürlich ist auch eine While-Schleife denkbar, in der man gegen das Enddatum prüft.

              Gruß
              Kalk

              1. Hello,

                Als Schleife verwendest Du anschließend foreach.

                Mit datePeriod habe ich keine Erfahrung, ist damit wirklich foreach sinnvoll?
                Wenn man bereits die Anzahl der Tage hat, böte sich eine einfache For-Schleife an. Natürlich ist auch eine While-Schleife denkbar, in der man gegen das Enddatum prüft.

                Ich bin für die If-Schleife

                scnr

                Liebe Grüße
                Tom S.

                --
                Die Krawatte ist das Kopftuch des Westens
                1. Hallo,

                  ich dachte an so etwas

                  $von = new DateTime("20.02.2017");
                  $bis = new DateTime("23.02.2017");
                   
                  $datum = $von->diff($bis);
                   
                  $i = 0;
                  
                  while($i < $datum->days) {
                  	
                     echo "$i";
                     echo "<br>";
                     $i++;
                  }
                  

                  Als Ergebnis erhalte ich jetzt 0, 1, 2 was ja richtig ist, da es drei Tage sind. Jetzt würde ich gerne noch das Datum ausgeben lassen zum jeweiligen Eintrag.

                  EDIT: Ich nutze dieses:
                  https://forum.selfhtml.org/self/2017/feb/19/datum-richtig-speichern/1687556#m1687556

              2. Tach!

                Als Schleife verwendest Du anschließend foreach.

                Mit datePeriod habe ich keine Erfahrung, ist damit wirklich foreach sinnvoll?

                Wenn ich mir die Beschreibung so ansehe, ist das genau die dafür richtige Kontrollstruktur. In PHP kann man in jede Klasse ein von Traversable abgeleitetes Interface implementieren und dann kann foreach darüber iterieren. So kann man Arrays simulieren, wo eigentlich keie da sind.

                Wenn man bereits die Anzahl der Tage hat, böte sich eine einfache For-Schleife an. Natürlich ist auch eine While-Schleife denkbar, in der man gegen das Enddatum prüft.

                Obige Klasse wird ausgehend vom Startdatum bei jedem Aufruf der next-Methode das nächste Datum ermitteln und zurückgeben, und wenn das Enddatum erreicht ist, gibt es den Abbruchwert womit sich das foreach beendet. Selber rechnen und Schleife formulieren ist nicht nötiger Mehraufwand.

                dedlfix.

              3. Natürlich ist auch eine While-Schleife denkbar, in der man gegen das Enddatum prüft.

                Und vorher prüfen, ob das Enddatum größer ist als das Startdatum. Sonst muss man nämlich rückwärts laufen 😉

            2. Hallo,

              danke dir, damit sollte mein Vorhaben klappen

              $begin = new DateTime( '20.02.2017' );
              $end = new DateTime( '23.02.2017' );
              
              $end = $end->modify( '+1 day' ); 
              
              $interval = new DateInterval('P1D');
              $daterange = new DatePeriod($begin, $interval ,$end);
              
              foreach($daterange as $date){
              
              	// Hier der Insert
                  echo $date->format("d.m.Y") . "<br>";
              }
              
      2. Achso, auf die Uhrzeit kommt es mir nicht an, es sind immer ganze Tage.

        Ja, solch Art von Datum gibt es, bereits die Maya haben einfach nur forlaufende Tage gezählt.

        MfG