Ankündigung

Einklappen
Keine Ankündigung bisher.

Excel-Formel übersetzen: wie vielter Wochentag ist ein Datum

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Excel-Formel übersetzen: wie vielter Wochentag ist ein Datum

    Hallo. Versuche eine Excel-Formel auf PHP zu übersetzten, die folgendes (unter Excel erfolgreich) bewerkstelligt:
    Sage mir, ob das Suchdatum, im Beispiel ein Sonnabend, der erste, zweite oder dritte Sonnabend im Monat ist.
    Die Excel-Formel dazu ist eigentlich ganz leicht:
    Code:
    =GANZZAHL((A1-MONATSENDE(A1;-1)+6)/7
    (wobei in der Zelle A1 ein Datum wie 12.05.2007 steht)

    Heraus kommt eine Zahl 1-5, die das gewünschte Resultat bringt.

    Mein Versuch in PHP bislang:
    um an den Monatsletzen zu kommen:
    1. Suche den 1. des Suchmonats (1.5.2007)
    2. Suche den 1. der Vormonats (1.4.2007)
    3. Berechne die Tage dazwischen (30)
    4. zähle diese Tage auf den 1. des Vormonats drauf (1.4.2007 + 30 ) und ich habe den Monatsletzten, mit dem ich dann weiterarbeiten kann.

    Mein 1. Problem nun ist, dass bei dem unten aufgeführten Code immer eine 30 herauskommt, auch wenn ich andere Monate als Startdatum setze.
    Was ist an der Herangehensweise falsch?

    Das 2. Problem besteht in der Weiterverarbeitung des Ergebnisses, um auf die Excel-Formel zu kommen.
    Hätte ich also das Datum des Letzten im Vormonat (vor dem Suchmonat), dann würde ich im nächsten Schritt doch von dem Suchdatum das Monatsende des Vormonats abziehen.
    Bei Excel kommt in diesem Fall beispielsweise 12 raus.
    Bei mir hingegen, wenn ich meine beiden mit mktime formatierten Datumswerte ausgeben will, kommt eine Zahl heraus , die ja noch für die Ausgabe bzw. Weiterverarbeitung formatiert werden müsste. In dem Beispiel werhalte ich die Zahl 691200.
    Mit date('d', $differenz) komme ich auch nicht auf die 12 wie bei Excel, sondern auf 01, wahrscheinlich weil der 1.1.1970 ausgegeben wird und meine mktime-Zahl nicht übersetzt wird.

    Wie müsste daher der Befehl aussehen, um aus der Differenz zweier mktime-Zeiten eine Zahl in Tagen bzw. anderen Einheiten zu bekommen, mit denen man im Sinne der Excel-Formel weiterarbeiten könnte?

    Wäre die Differenz zwischen Suchdatum und Monatletztem also klar, müsste der Rest der Formel ja wohl klappen mit:
    ($diff +6)/7 und dann noch mit ceil oder floor runden.

    Hier mein Code:
    Code:
    $suchdatum = '12.05.2007';
    $suchdatum_erster = mktime(0,0,0,substr($suchdatum,3,2),1,substr($suchdatum,-4));//macht 1.5.2007
    $suchdatum_vormonat_erster = mktime(0,0,0,substr($suchdatum,3,2)-1,1,substr($suchdatum,-4));//macht 1.4.2007
    
    $suchdatum_ersterd = date('d.m.Y', $suchdatum_erster);//macht 1.5.2007 formatiert
    $suchdatum_vormonat_ersterd = date('d.m.Y', $suchdatum_vormonat_erster);//macht 1.4.2007 formatiert
    
    //Für die weitere Verarbeitung werden die Zeitangaben aus den beiden gefundenen Datumswerten extrahiert
    $x_jahr = substr($suchdatum_ersterd,-4) ;
    		 $x_monat = substr($suchdatum_ersterd,3,2) ;
    		 $x_tag = substr($suchdatum_ersterd,0,2) ;
    
    $y_jahr = substr($suchdatum_vormonat_ersterd,-4) ;
    		 $y_monat = substr($suchdatum_vormonat_ersterd,3,2) ;
    		 $y_tag = substr($suchdatum_vormonat_ersterd,0,2) ;
    
    //Jetzt die Differenz
    $diff = mktime ( 0, 0, 0, $x_monat, $x_tag, $x_jahr) - mktime ( 0, 0, 0, $y_monat, $y_tag, $y_jahr);
    
    echo abs($diff/(60*60*24));
     //Kommt immer 30 raus
     //echo ceil(($diff +6)/7);


  • #2
    Machs net so kompliziert..

    PHP-Code:
    <?php
    function calcWeekday($date null)
    {
      if (
    is_null($date)) {
        
    $date date('Y-m-d');
      }
      list (
    $y$m$d) = explode('-'$date);
      return array(
    'weekday' => date('l'$date), 'count' => ceil($d 7));
    }
    list (
    $weekday$count) = calcWeekday();
    echo 
    "$weekday$count";
    ?>
    Schau dir dazu auch nochmal date() an:
    http://de.php.net/date
    Um Datumsangaben in anderen Sprach-/Zeitzonen-Formaten auszugeben, sollten Sie die Funktionen setlocale() und strftime() benutzen.

    Kommentar


    • #3
      Hey, das klappt ja, (nicht das ich daran gezweifelt hätte), besten Dank.
      Zitat von Zergling
      Machs net so kompliziert.
      Dann frage ich mal weiter:
      Mein nächster Schritt wäre jetzt zu erreichen, in einem bestimmten Monat den, sagen wir, 2. Samstag anzuzeigen.

      Dazu würde ich:
      1. Den Anfang des gesuchten Monats errechnen
      2. Den Wochentag bestimmen (1-7 bz. 0-6)
      3. Das Ergebnis der Funktion *7 mit diesem Wochentagswert am Monatsersten addieren, vorausgesetzt es handelt sich um den gleichen Wochentag. Ansonsten für jeden möglichen Tag der Woche eine eigene Berechnung anfertigen.
      Oder geht es auch einfacher?

      Kommentar


      • #4
        Hallo,
        ich würde das prozedural dann so implementieren:
        PHP-Code:
        <?php
        function getDateByWeekday($year$month$weekday$count)
        {
            
        // letzten Tag des Vormonats errechnen
            // ab dann den nächsten übergebenen Wochentag suchen (lassen mit strtotime())
            // da er ab dem Folgetag gesucht wird, benötigen wir den letzten des Vormonats
            
        $firstWeekday date('j'strtotime("next $weekday"mktime(000$month0$year)));
            
        // jetzt haben wir den ersten abgefragten Wochentag des Monats
            // jetzt einfach mit dem $count aufsummieren (wird 3 übergeben, wird 14 addiert usw. (und nicht 21), da wir den ersten Wochentag ja bereits haben, sonst würden wir hier ja auch 7 addieren und kämen ungewollt zum 2. Wochentag des Monat
            
        $requestedDay   $firstWeekday + ($count 1) * 7;
            return 
        date('Y-m-d'mktime(000$month$year$requestedDay));
            
        // jetzt können wir sogar den 10. oder beliebigsten Faktor eines Wochentages angeben
        }

        // Start Bundesliga-Saison 2007/2008 am 2. Freitag des August 2007
        echo getDateByWeekday(20078'Friday'2);
        // = 2007-08-10
        ?>
        Wobei ich statt "Friday" eher den Weekday-Index aus date("l") verwenden würde, kannst du ja grad selbst machen, falls du das möchtest.

        strtotime() ist wirklich sehr mächtig, wobei ich bei Schleifendurchläufen dann versuchen würde darauf zu verzichten. Aber einmalig ist das in Ordnung.

        Kommentar


        • #5
          Hm, bei der Funktion kommt bei mir was anderes als 2007-08-10
          raus.
          echo getDateByWeekday('2007', '8', 'Friday', 2); = 2016-01-28

          Kommentar


          • #6
            Hoppla, hab 2 Parameter von mktime() vertauscht .. findest doch bestimmt selbst wo und welche

            Kommentar


            • #7
              Zitat von Zergling
              Hoppla, hab 2 Parameter von mktime() vertauscht .. findest doch bestimmt selbst wo und welche
              Okay, das Jahr nach hinten und die Tage davor, Scheiß Syntax immer, dachte schon es sei strtotime.
              Aber damit kann ich jetzt erst mal arbeiten, danke.

              Kommentar


              • #8
                Warum klappt das hier nicht?
                Code:
                $test = "2007, 8, 'Friday', 2";
                echo getDateByWeekday($test);
                Versuche schon die ganze Zeit Friday zu maskieren, aber ich bekomme kein Ergebnis aus der Funktion sobald ich die Werte in eine Variable schreibe.

                Nachtrag: Okay, das hier klappt zumindest
                Code:
                $test1 = "2007";
                $test2 = "8";
                $test3 = "Friday";
                $test4 = "3";
                
                echo getDateByWeekday($test1, $test2, $test3, $test4);

                Kommentar


                • #9
                  Zitat von Zergling
                  ich würde das prozedural dann so implementieren:
                  Hier schmeißt er mir ein falsches Datum aus: Gebe mir den 1. Dienstag im August 2007 (7. August)

                  Code:
                  $test1 = "2007";
                  $test2 = "8";
                  $test3 = "Tuesday";
                  $test4 = "1";
                  echo getDateByWeekday($test1, $test2, $test3, $test4);
                  = 2007-08-31

                  Kommentar


                  • #10
                    Zitat von webazubi
                    Warum klappt das hier nicht?
                    Code:
                    $test = "2007, 8, 'Friday', 2";
                    echo getDateByWeekday($test);
                    Zumindest das solltest Du Dir durch Blick in ein PHP Basic Tutorial selbst beantworten können.
                    --

                    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                    --

                    Kommentar


                    • #11
                      Zitat von nikosch77
                      Zumindest das solltest Du Dir durch Blick in ein PHP Basic Tutorial selbst beantworten können.
                      Das hatte ich ja mit dem Nachtrag noch aufgeklärt.
                      Dennoch klappt die Funktion nicht bei dem Beispiel 1. Dienstag im August. Werde da wohl noch ein paar Kontrollen einbauen.

                      Kommentar


                      • #12
                        Zitat von webazubi
                        Zitat von nikosch77
                        Zumindest das solltest Du Dir durch Blick in ein PHP Basic Tutorial selbst beantworten können.
                        Das hatte ich ja mit dem Nachtrag noch aufgeklärt.
                        Dennoch klappt die Funktion nicht bei dem Beispiel 1. Dienstag im August. Werde da wohl noch ein paar Kontrollen einbauen.
                        Versuch doch lieber zu debuggen und die Ursache zu finden, ..
                        Habe gerade keine Zeit dafür.

                        Kommentar


                        • #13
                          Ich glaube in der Funktion muss es statt 0 als Tagesangabe eher 1 heißen:
                          Code:
                          $firstWeekday = date('j', strtotime("next $weekday", mktime(0, 0, 0, $month, 1, $year)));
                          Ich teste noch einige Termine durch, aber erste Tests sehen gut aus

                          Kommentar


                          • #14
                            Möglich. Das macht für das Bsp. aber keinen Unterschied, oder? Jedenfalls ist die Reihenfolge einfach falsch. Richtig:
                            PHP-Code:
                            <?
                            return date('Y-m-d', mktime(0, 0, 0, $month, $requestedDay, $year));
                            int mktime ( [int Stunde [, int Minute [, int Sekunde [, int Monat [, int Tag [, int Jahr [, int is_dst]]]]]]] )
                            --

                            „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                            Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                            --

                            Kommentar


                            • #15
                              Zitat von nikosch77
                              Reihenfolge einfach falsch
                              Das war ja schon geklärt
                              Okay, das Jahr nach hinten und die Tage davor,
                              Die Funktion bei mir sieht so aus
                              Code:
                              function getDateByWeekdayx($year, $month, $weekday, $count)
                              {
                              $firstWeekday = date('j', strtotime("next $weekday", mktime(0, 0, 0, $month, 1, $year)));
                              $requestedDay   = $firstWeekday + ($count - 1) * 7;
                                  return date('Y-m-d', mktime(0, 0, 0, $month, $requestedDay, $year));
                              }
                              Alle Tests bislang bestanden.

                              Kommentar

                              Lädt...
                              X