Fjorden: Datum eines Wochentags bestimmen über die Woche

Hi,

ich habe da irgendwie gerade ne Denkblockade:

Ich bekomme die Woche geliefert und möchte dazu jetzt das Datum vom Montag bestimmen. Wie?

Ich schau mir jetzt schon ewig die Parameter für mktime an, aber ich glaube da werde ich nichts mit...

Hat da einer einen kleinen Tipp für mich?

Gruß

  1. echo $begrüßung;

    Ich bekomme die Woche geliefert und möchte dazu jetzt das Datum vom Montag bestimmen. Wie?
    Ich schau mir jetzt schon ewig die Parameter für mktime an, aber ich glaube da werde ich nichts mit...

    ... anfangen können? Nicht im ersten Schritt. Wenn du einen Timestamp haben möchtest, brauchst du es im zweiten Schritt (vielleicht auch gmmktime(), je nachdem, ob du Lokalzeit oder UTC hast).

    Der erste Schritt kann, PHP 5.1.0 vorausgesetzt[1], der Einsatz von strptime() sein. Bei meinen Versuchen hat es leider nur kein richtiges Ergebnis gebracht, wenn man die ISO-Norm für die Bestimmung der ersten Woche %G oder %V verwendet. Die anderen Formatzeichen - %U und %W probierte ich - lieferten bessere Werte. Allerdings müsstest du hier ggf. eine Korrektur der Wochennummer vornehmen, wenn die erste Woche im alten Jahr beginnt.

    [1] genauer: >= 5.2.0, vorher hatte es eine fehlerhafte Implementierung.

    echo "$verabschiedung $name";

    1. (vielleicht auch gmmktime(), je nachdem, ob du Lokalzeit oder UTC hast).
      aber bei gmmktime kann ich doch keine Woche angeben:

      int gmmktime  ([ int $Stunde  [, int $Minute  [, int $Sekunde  [, int $Monat  [, int $Tag  [, int $Jahr  [, int $is_dst  ]]]]]]] )

      und bei strptime() finde ich auch keine Angaben, wie man mit Wochen arbeitet?

      Kannst Du da noch mal genauer werde...?

      Gruß

      1. und bei strptime() finde ich auch keine Angaben, wie man mit Wochen arbeitet?

        Hier stehen die Formate die man auch für strptime verwenden kann => http://de.php.net/manual/de/function.strftime.php

        1. also sorry, aber irgendwie kriege ich das nicht gerallt.

          Die Beispiele da zeigen mir ja lediglich, wie ich aus einem Datum die Kalender-Woche ermittel.

          Das war aber ja nicht mein Zeil.

          Bei mir ist es genau anders herum.
          Ich habe nur das Jahr und die Kalenderwoche und möchte daraus jetzt den ersten Wochentag, also das Datum vom Montag der entsprechenden Kalenderwoche ermitteln.

          Das muss doch machbar sein - oder reden wir die ganze Zeit aneinander vorbei?

          Gruß und danke für die Geduld

          1. echo $begrüßung;

            Die Beispiele [bei strftime()] da zeigen mir ja lediglich, wie ich aus einem Datum die Kalender-Woche ermittel.
            Bei mir ist es genau anders herum.

            Ja, genau andersrum versucht die Funktion strptime() aus einem formatierten String und einer Format-Angabe wieder eine Zeit zu ermitteln.

            Ich habe nur das Jahr und die Kalenderwoche und möchte daraus jetzt den ersten Wochentag, also das Datum vom Montag der entsprechenden Kalenderwoche ermitteln.

            Das Jahr, vierstellig, hat das Format-Zeichen %Y.
            Für die Wochennummer gibt es %U, %V und %W (Das %G aus meiner ersten Posting war nicht richtig.)
            Außerdem soll der erste Tag der Woche Montag sein: %u=1.

            Wenn du als Formatierung angibst: %Y-%V-%u und einen Wert 2007-6-1 (Jahr:2007, Woche:6 gemäß ISO, Wochentag: Montag) und das dem strptime() zum Parsen gibst, bekommst du:

            Array ( // gekürzt
                [tm_mday] => 0
                [tm_mon] => 0
                [tm_year] => 107
                [tm_wday] => 1
            )

            Das ist nicht verwendbar, weil mday und mon jeweils 0 sind. Nächster Versuch mit %Y-%W-%u:

            Array ( // gekürzt
                [tm_mday] => 5
                [tm_mon] => 1
                [tm_year] => 107
                [tm_wday] => 1 )

            Das entspricht dem 5. Februar 2007 - stimmt. Noch ein Versuch mit dem Jahr 2008

            Array ( // gekürzt
                [tm_mday] => 11
                [tm_mon] => 1
                [tm_year] => 108
                [tm_wday] => 1 )

            Nicht verwendbar, hätte der 4. sein müssen. Hier ist eine Korrektur der Wochennummer notwendig. Schauen wir mal durch, wie sich das ab 2000 verhält:

            2000 (1.Jan=Sa) stimmt
            2001 (1.Jan=Mo) stimmt
            2002 (1.Jan=Di) stimmt nicht
            2003 (1.Jan=Mi) stimmt nicht
            2004 (1.Jan=Do) stimmt nicht
            2005 (1.Jan=Sa) stimmt
            2006 (1.Jan=So) stimmt
            2007 (1.Jan=Mo) stimmt
            2008 (1.Jan=Di) stimmt nicht
            2009 (1.Jan=Do) stimmt nicht
            2010 (1.Jan=Fr) stimmt

            Finde nun die Regel, wann eine Korrektur notwendig ist, dann kannst du die beim Verwenden von strptime() berücksichtigen.

            echo "$verabschiedung $name";

            1. Hi,

              Finde nun die Regel, wann eine Korrektur notwendig ist, dann kannst du die beim Verwenden von strptime() berücksichtigen.

              Hmm, also mein Vorschlag kommt ohne Regel aus ... ;-)

              Gruß, Cybaer

              --
              Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
              1. echo $begrüßung;

                Finde nun die Regel, wann eine Korrektur notwendig ist, dann kannst du die beim Verwenden von strptime() berücksichtigen.
                Hmm, also mein Vorschlag kommt ohne Regel aus ... ;-)

                Ja, dafür ist er aber auch falsch.

                echo "$verabschiedung $name";

                1. Hi,

                  Hmm, also mein Vorschlag kommt ohne Regel aus ... ;-)
                  Ja, dafür ist er aber auch falsch.

                  Tip auf die Schnelle, wo der gedankliche Fehler lag?
                  Ich meine: prinzipiell, nicht im Detail (da der eben nur eine spontane Idee war).

                  Gruß, Cybaer

                  --
                  Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                  1. echo $begrüßung;

                    Hmm, also mein Vorschlag kommt ohne Regel aus ... ;-)
                    Ja, dafür ist er aber auch falsch.
                    Tip auf die Schnelle, wo der gedankliche Fehler lag?

                    Weiß ich nicht, weil du deine Gedanken nicht offenbart hast. Du hast einfach nur eine Formel hingeschrieben ohne weitere Erläuterung. Was soll das +1 und -1 in der Formel bewirken?

                    Ich meine: prinzipiell, nicht im Detail (da der eben nur eine spontane Idee war).

                    Nun, prinzipiell hat ein Tag nur 24 Stunden, keine 60 :-)

                    Neuer Timestamp: Jahresbeginn + (Woche+1)*7*60*60*60 - 1
                    Und dann mttels dieses TS mit strotime() den letzten Montag bestimmen ('last monday').

                    Aber mal abgesehen von dem 24/60-Fehler, habe ich das mal in Code gegossen. Im Vergleich dazu noch eine Umsetzung mit ab PHP 5.1 verfügbaren DateTime-Klasse.

                    <pre>  
                    <?php  
                    date_default_timezone_set('Europe/Berlin');  
                    function cybear($year, $week) {  
                     $jan1 = mktime(0, 0, 0, 1, 1, $year);  
                     $ts = $jan1 + ($week + 1) * 7 * 24 * 60 * 60 - 1;  
                     $tsMon = strtotime('last monday', $ts);  
                     echo $year, ',', $week, ' - ', date('Y-m-d  W', $tsMon), ' - ', date('W', $jan1), ' # ';  
                    }  
                      
                    function php51($year, $week) {  
                      $date = new DateTime;  
                      $date->setISODate($year, $week, 1);  
                      $date->setTime(0, 0, 0);  
                      echo $date->format('Y-m-d  W'), "\n";  
                    }  
                      
                    // prinzipieller Test  
                    cybear(2007, 1); php51(2007,1);  
                    cybear(2007, 2); php51(2007,2);  
                    cybear(2007, 3); php51(2007,3);  
                    // Sommerzeitumschaltung  
                    cybear(2007, 12); php51(2007,12);  
                    cybear(2007, 13); php51(2007,13);  
                    cybear(2007, 14); php51(2007,14);  
                    echo "\n";  
                    // gleiche Woche, aber andere Jahre  
                    cybear(2000, 6); php51(2000, 6);  
                    cybear(2001, 6); php51(2001, 6);  
                    cybear(2002, 6); php51(2002, 6);  
                    cybear(2003, 6); php51(2003, 6);  
                    cybear(2004, 6); php51(2004, 6);  
                    cybear(2005, 6); php51(2005, 6);  
                    cybear(2006, 6); php51(2006, 6);  
                    cybear(2007, 6); php51(2007, 6);  
                    cybear(2008, 6); php51(2008, 6);  
                    cybear(2009, 6); php51(2009, 6);  
                    cybear(2010, 6); php51(2010, 6);
                    

                    Das erzeugt diese Ausgabe:
                    Eingangswerte - CybearDatum  Wochennummer - Wochennummer vom 1.Jan. # PHP51-Datum  Wochennummer
                    2007,1  - 2007-01-08  02 - 01 # 2007-01-01  01
                    2007,2  - 2007-01-15  03 - 01 # 2007-01-08  02
                    2007,3  - 2007-01-22  04 - 01 # 2007-01-15  03
                    2007,12 - 2007-03-26  13 - 01 # 2007-03-19  12
                    2007,13 - 2007-04-02  14 - 01 # 2007-03-26  13
                    2007,14 - 2007-04-09  15 - 01 # 2007-04-02  14

                    Mein Fazit: Immun gegen Sommerzeitumschaltung, aber immer eine Woche zu spät.

                    2000,6 - 2000-02-14  07 - 52 # 2000-02-07  06
                    2001,6 - 2001-02-12  07 - 01 # 2001-02-05  06
                    2002,6 - 2002-02-11  07 - 01 # 2002-02-04  06
                    2003,6 - 2003-02-17  08 - 01 # 2003-02-03  06
                    2004,6 - 2004-02-16  08 - 01 # 2004-02-02  06
                    2005,6 - 2005-02-14  07 - 53 # 2005-02-07  06
                    2006,6 - 2006-02-13  07 - 52 # 2006-02-06  06
                    2007,6 - 2007-02-12  07 - 01 # 2007-02-05  06
                    2008,6 - 2008-02-11  07 - 01 # 2008-02-04  06
                    2009,6 - 2009-02-16  08 - 01 # 2009-02-02  06
                    2010,6 - 2010-02-15  07 - 53 # 2010-02-08  06

                    Mein Fazit: Ein bis zwei Wochen zu spät. Recht unregelmäßig, keine Abhängigkeit vom 1. Januar zu erkennen.

                    echo "$verabschiedung $name";

                    1. Hi,

                      Weiß ich nicht, weil du deine Gedanken nicht offenbart hast. Du hast einfach nur eine Formel hingeschrieben ohne weitere Erläuterung.

                      Ich dachte: das Prinzip wird schon klar. :-)

                      Was soll das +1 und -1 in der Formel bewirken?

                      Ein Ausgleich für die "Abhängigkeit vom 1. Januar" (eine Woche drauf und dann 1 Sekunde runter).

                      Nun, prinzipiell hat ein Tag nur 24 Stunden, keine 60 :-)

                      :-)) Mein Chef hat mich belogen! ;->

                      Mein Fazit: Ein bis zwei Wochen zu spät. Recht unregelmäßig, keine Abhängigkeit vom 1. Januar zu erkennen.

                      Ja, der spontan gedachte Ausgleich war "overoptimistic". ;-)

                      Wenn man stattdessen einfach eine halbe Woche nimmt, klappt es auch ohne PHP 5.1:

                      function mondayOfKW($year,$kw) {  
                       $daySeconds=86400; // 24(! ;-))*60*60  
                       $middleOfKW=mktime(0,0,0,1,1,$year)+($kw*7*$daySeconds)-(3*$daySeconds);  
                       return strtotime('last monday',$middleOfKW);  
                      }  
                      
                      

                      Und als Beispiel:

                      for($j=2000;$j<=2010;$j++) {  
                       for($w=1;$w<=52;$w++) {  
                        $mondayTS=mondayOfKW($j,$w);  
                        echo '<div style="background-color:'.(($w==date('W',$mondayTS))?'green':'red').'">'.$j.'/'.$w.': '.date('l Y-m-d (W)',$mondayTS.'</div>';  
                       }  
                      }  
                      
                      

                      Gruß, Cybaer

                      --
                      Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
  2. Hi,

    Ich bekomme die Woche geliefert und möchte dazu jetzt das Datum vom Montag bestimmen. Wie?

    Gedankenansatz:

    Neuer Timestamp: Jahresbeginn + (Woche+1)*7*60*60*60 - 1

    Und dann mttels dieses TS mit strotime() den letzten Montag bestimmen ('last monday').

    Gruß, Cybaer

    --
    Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
  3. Hallo,

    ich habe da irgendwie gerade ne Denkblockade:

    Ich bekomme die Woche geliefert und möchte dazu jetzt das Datum vom Montag bestimmen. Wie?

    Ich hatte dazu bereits etwas geschrieben (bitte auch meine Antwort auf mich selbst lesen!) - hilft Dir das weiter?

    Viele Grüße,
    Christian