Sophie: DateTime -3 day

Hallo,

ich habe direkt noch eine Frage. Ich nutze um ein Datum auszurechnen die PHP Funktion DateTime

$begin = new DateTime( '20.06.2017' );
$date = $begin->modify( '-3 day' )->format('d.m.Y');
echo $date; //17.06.2017

So weit klappt alles wunderbar. Jetzt möchte ich ein Schritt weiter gehen. Das Wochenende soll nicht mitberechnet werden. Sprich als Ergebnis sollte nach der neuen Rechnung der 15.06.2017 raus kommen. Samstag / Sonntag soll ausgeschlossen werden.

Ich sehe in der Dokumentation nicht, dass das möglich ist? Habt ihr eine Idee, wie ich dieses umsetzen könnte?

akzeptierte Antworten

  1. Hello,

    $begin = new DateTime( '20.06.2017' );
    $date = $begin->modify( '-3 day' )->format('d.m.Y');
    echo $date; //17.06.2017
    

    So weit klappt alles wunderbar. Jetzt möchte ich ein Schritt weiter gehen. Das Wochenende soll nicht mitberechnet werden. Sprich als Ergebnis sollte nach der neuen Rechnung der 15.06.2017 raus kommen. Samstag / Sonntag soll ausgeschlossen werden.

    Du wirst wohl um eine eigene Funktion/Methode nicht herum kommen.

    ->format('N')liefert Dir die Nummer des Wochentages (Mo=1, So=7).

    Und dann musst Du eben schauen, wieviele #6 und #7 im voraussichtlichen Zeitraum enthalten sein können. Also erst einmal durch 5 teilen und mit 7 multiplizieren und dann schauen, ob vor oder in einem Wochenende gestartet wird mit der Berechnung. Usw...

    Liebe Grüße
    Tom S.

    --
    Es gibt nichts Gutes, außer man tut es
    Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
  2. Tach!

    $begin = new DateTime( '20.06.2017' );
    $date = $begin->modify( '-3 day' )->format('d.m.Y');
    

    Das Wochenende soll nicht mitberechnet werden.

    Hier ist es gut zu wissen, dass dem modify eine Funktion namens strtotime zugrundeliegt. Das ergibt das erste Suchstichwort strtotime. Dazu noch work days und das ergibt ein paar Fundstellen mit Lösungen, denen nicht von anderen widersprochen wurde, also wohl funktonieren werden. weekday sagen sie, heißt das gesuchte Wort. Beachte aber, dass es auch noch Feiertage gibt, die damit nicht übersprungen werden.

    dedlfix.

    1. Hello,

      $begin = new DateTime( '20.06.2017' );
      $date = $begin->modify( '-3 weekday' )->format('d.m.Y');
      

      Das Wochenende soll nicht mitberechnet werden.

      weekday sagen sie, heißt das gesuchte Wort.

      Interessante Sache, wenn's funktioniert. :-)
      Sind die Optionen auch (n)irgendwo bei PHP dokumentiert!?

      Edit: Ok, vielleicht hier?

      Liebe Grüße
      Tom S.

      --
      Es gibt nichts Gutes, außer man tut es
      Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
      1. Hallo Tom,

        danke für den Link. Aber um ehrlich zu sein verstehe ich davon nichts. Könntest du mir vielleicht sagen wie ich dieses auf mein Beispiel anwenden könnte?

        EDIT: So sollte es klappen:
        https://forum.selfhtml.org/self/2017/jun/19/datetime-3-day/1696864#m1696864

        1. Tach!

          danke für den Link. Aber um ehrlich zu sein verstehe ich davon nichts. Könntest du mir vielleicht sagen wie ich dieses auf mein Beispiel anwenden könnte?

          Das ist ein Bugreport. Der dort gemeldete Fehler wurde in Version 5.5 gefixt. Wenn du also ein aktuelles PHP verwendest, bist du davon nicht betroffen.

          dedlfix.

          1. Hello,

            Das ist ein Bugreport. Der dort gemeldete Fehler wurde in Version 5.5 gefixt. Wenn du also ein aktuelles PHP verwendest, bist du davon nicht betroffen.

            Irgendwie habe ich aus dem Bugreport nicht sehen können, wann das repariert wurde. Da steht zwar "closed" aber ich bin wohl zu blind, ein Datum zu sehen?

            Liebe Grüße
            Tom S.

            --
            Es gibt nichts Gutes, außer man tut es
            Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
            1. Tach!

              Irgendwie habe ich aus dem Bugreport nicht sehen können, wann das repariert wurde. Da steht zwar "closed" aber ich bin wohl zu blind, ein Datum zu sehen?

              Ganz unten beim Fixed-in-5.5-Eintrag steht auch ein Datum. Aber die Versionsummer ist wichtiger als das Datum.

              dedlfix.

      2. Tach!

        weekday sagen sie, heißt das gesuchte Wort.

        Interessante Sache, wenn's funktioniert. :-)

        Siehe dort ganz unten.

        Ist das auch nirgendwo bei PHP dokumentiert?

        Ja, wenn man dem Verweis zu Date and Time Formats und weiter zu Relative Formats folgt, ist es gleich in der zweiten Zeile gelistet. Aber leider ohne Erklärung, was das konkret bewirkt.

        dedlfix.

    2. Hallo dedlfix,

      danke für deine Erklärung. So sollte es funktionieren, wenn ich dieses richtig verstanden habe: https://stackoverflow.com/questions/4261179/working-days-mon-fri-in-php

      $begin = new DateTime( '20.06.2017' );
      $date = $begin->modify( '-3 weekdays' )->format('d.m.Y');
      echo $date;
      

      Wie ich das mit den Feiertagen mache muss ich mal schauen.

      1. Hello,

        Wie ich das mit den Feiertagen mache muss ich mal schauen.

        Meine Antwort ist leider einem falschen Tastendruck zum Opfer gefalle. Nur kurz: vielleicht hilft Dir das? MySQL-Tabelle Feiertage

        Liebe Grüße
        Tom S.

        --
        Es gibt nichts Gutes, außer man tut es
        Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
        1. Tach!

          Wie ich das mit den Feiertagen mache muss ich mal schauen. vielleicht hilft Dir das? MySQL-Tabelle Feiertage

          Naja, nur teilweise. So eine vorgefertigte Liste ist ganz nett, aber nun auch nicht sehr schwer herzustellen. Die Hauptarbeit steckt in dem Code, der erkennt, dass da in dem fraglichen Zeitraum ein Feiertag war und auf einen Arbeitstag gefallen ist. Feiertage am Wochenende müssen ausgeklammert werden. Auch dass das Ergebnis des Feiertagsüberspringens nicht auf einem Wochenende gelandet ist, muss man berücksichtigen. Vermutlich ist es einfacher, selbst die Tage unter Berücksichtigung der Faktoren zu zählen als das Ergebnis von strtotime/date::modify nachträglich korrigieren zu wollen.

          dedlfix.

          1. Hallo dedlfix,

            meine Idee war / ist folgende:

            Mein Datum steckt in

            $date; 
            

            Jetzt habe ich eine Tabelle wo alle Feiertage hinterlegt sind. Ich schau in die Spalte ob ein Eintrag vorhanden ist der gleich meinem $date ist. Wenn ja nehme ich den Wert und schick diesen nochmals durch die Funktion, dann sollte ich doch das Datum bekommen, welches ich benötige.

            Oder denke ich hier viel zu kompliziert oder sogar zu einfach?

            1. Tach!

              Jetzt habe ich eine Tabelle wo alle Feiertage hinterlegt sind. Ich schau in die Spalte ob ein Eintrag vorhanden ist der gleich meinem $date ist. Wenn ja nehme ich den Wert und schick diesen nochmals durch die Funktion, dann sollte ich doch das Datum bekommen, welches ich benötige.

              Jein. Kommt auch darauf an, wie genau die Tage gezählt werden sollen. Angenommen es ist Donnerstag und Mittwoch war ein Feiertag. Drei Tage zurück ist Montag. Aber soll der arbeitsfreie Mittwoch berücksichtigt werden und das Ergebnis dann Sonntag sein? Der dann auch wieder wegen der Wochenendreglung zusammen mit dem Sonnabend übersprungen werden muss, gegebenenfalls zuzüglich weiterer freier oder Feiertage?

              dedlfix.

            2. Hello,

              Oder denke ich hier viel zu kompliziert oder sogar zu einfach?

              Mit MySQL-Datenbank wäre es erheblich einfacher!

              Wenn die Tabelle passend aufbereitet ist mit Staat, Bundesland, Jahr, Feiertage, (Wochenenden), ...
              dann ist das nbur ein einziges Query mit einem Offset und Limit und du hast sofort das Zieldatum als Result.

              Liebe Grüße
              Tom S.

              --
              Es gibt nichts Gutes, außer man tut es
              Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
              1. Tach!

                Oder denke ich hier viel zu kompliziert oder sogar zu einfach?

                Mit MySQL-Datenbank wäre es erheblich einfacher!

                Wenn die Tabelle passend aufbereitet ist mit Staat, Bundesland, Jahr, Feiertage, (Wochenenden), ...
                dann ist das nbur ein einziges Query mit einem Offset und Limit und du hast sofort das Zieldatum als Result.

                Hmm, fällt mir grad nicht ein, wie ich das lösen würde, außer schrittweise die Tage zu dekrementieren und jeden Tag einzeln nachzuschlagen. Jedenfalls vom Prinzip her. Praktisch würde ich das auf eine Query reduzieren, die die Tage von zwei Wochen holt und dann gegen die Ergebnismenge prüfen statt separater Datenbankabfragen.

                dedlfix.

                1. Hello,

                  Mit MySQL-Datenbank wäre es erheblich einfacher!

                  Wenn die Tabelle passend aufbereitet ist mit Staat, Bundesland, Jahr, Feiertage, (Wochenenden), ...
                  dann ist das nbur ein einziges Query mit einem Offset und Limit und du hast sofort das Zieldatum als Result.

                  Hmm, fällt mir grad nicht ein, wie ich das lösen würde, außer schrittweise die Tage zu dekrementieren und jeden Tag einzeln nachzuschlagen. Jedenfalls vom Prinzip her. Praktisch würde ich das auf eine Query reduzieren, die die Tage von zwei Wochen holt und dann gegen die Ergebnismenge prüfen statt separater Datenbankabfragen.

                  Pseudocode:

                  zeige alle Datensätze aus Kalenderjahr 
                      für 
                         Staat = $staat, 
                         Land = $land, 
                         nicht(Feiertag), 
                         nicht(Sa|So), 
                      offset $wievielWerktage, 
                      limit 1` 
                  

                  In der Realität musst Du dir das vermutlich besser zusammenjoinen aus zwei (oder drei) Tabellen.

                  Liebe Grüße
                  Tom S.

                  --
                  Es gibt nichts Gutes, außer man tut es
                  Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
                  1. Tach!

                    Pseudocode:

                    zeige alle Datensätze aus Kalenderjahr 
                        für 
                           Staat = $staat, 
                           Land = $land, 
                           nicht(Feiertag), 
                           nicht(Sa|So), 
                        offset $wievielWerktage, 
                        limit 1` 
                    

                    Naja, an sowas dachte ich auch. Und da fällt mir grad auf, nicht "zeige" sondern "zähle". Aber andererseits bringt weder das eine noch das andere die richtige Anzahl, weil da Feiertage/Wochenenden außerhalb des Offset nicht berücksichtigt werden, auf die das Ergebnis dann fallen kann. Oder übersehe ich da was?

                    dedlfix.

                    1. Hello,

                      entweder ich sitze da jetzt verkehrt herum auf dem Pferd, oder Du siehst nicht, dass "Wochenendtage" ja aufgrund des Querys gar nicht zur Ergebnismenge gehören dürfen und daher gar nicht in Zählung der Offsetzeilen fallen würden.

                      Reite ich in die falsche Orientierung? Die Richtung müsste ja schon stimmen ;-)

                      Ich habe sowas mal für eine Urlaubsanspruchverwaltung unter besonderer Berücksichtigung von Bundesland, Wochenenden, Feiertagen, Kernbetriebsurlaub und Krankheitstagen gemacht. Leider finde ich es im Moment nicht. Ich erinnere mich aber, dass es nur zwei Tabellen im Kernmodul gab: das ganze Jahr mit den gesetzlichen Feiertagen (also 365 oder 366 DS) und die Ausnahmen für die Bundesländer. Hinzu kamen dann die Tabellen für die Mitarbeier. Dafür war ich aber nicht mehr zuständig.

                      Liebe Grüße
                      Tom S.

                      --
                      Es gibt nichts Gutes, außer man tut es
                      Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
                      1. Tach!

                        entweder ich sitze da jetzt verkehrt herum auf dem Pferd, oder Du siehst nicht, dass "Wochenendtage" ja aufgrund des Querys gar nicht zur Ergebnismenge gehören dürfen und daher gar nicht in Zählung der Offsetzeilen fallen würden.

                        Moment mal, du hast eine Tabelle (oder eine zweite für Schaltjahre), die für jeden Tag einen Eintrag hat, und zu diesem die Metadaten, wie Feiertag oder Wochentagsname? Dann wird es gehen. Ich ging von einer Tabelle aus, die nur die besonderen Tagen enthält. Die anderen Tage sind ja im Prinzip redundant und deren Werte lassen sich einfach errechnen. Nur kann man sie dann auch kaum in einer (einfachen) Query berücksichtigen.

                        dedlfix.

                        1. Hello,

                          Moment mal, du hast eine Tabelle (oder eine zweite für Schaltjahre)

                          Ich hatte es damals erst mit einer virtuellen Tabelle für die "normalen" Datensätze versucht. Aber entweder war ich zu blöd oder MySQL konnte es tatsächlich noch nicht. Die virtuelle Tabelle wird ja nur dafür benötigt, dass es für jeden Tag des Jahres einen DS zum Joinen gibt. Das ist die maximale Obermenge und die wird dann durch die eigentliche Feiertags-Tabelle reduziert.

                          Liebe Grüße
                          Tom S.

                          --
                          Es gibt nichts Gutes, außer man tut es
                          Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
          2. Hello,

            pro Staat, pro Bundesland, pro Jahr anders...
            Die Tabelle wird wohl für jedes Jahr angeboten, wie ich das sehe.

            Da muss man also nichts mehr erfassen, sondern muss nur noch eine passende Abfrage für die "unbelasteten" Tage mit dem richtigen Offset und Limit ausführen und hat sofort das Zieldatum.

            Liebe Grüße
            Tom S.

            --
            Es gibt nichts Gutes, außer man tut es
            Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.