Kalenderwochen bis Ende folgendes Jahr berechnen

caramba12321

blödefragensteller
Hi Leute, ich möchte gerne alle Kalenderwochen numerisch mit Start und End Datum von nun an bis zum Ende des folgenden Jahres berechnen. Also: KW 15 (12.04.2010 - 18.04.2010) KW16 ... ... .. .. Hat jemand ne Idee wie ich das mache? Ich möchte das nachher im Endeffekt wie eine Art Kalender ausgeben, User sollen KW weise bestimmte Dienste buchen können.. Vielleicht kennt ja auch jemand schon eine Klasse oder ähnliches? Danke und Gruß Caramba
 
Hi das geht am besten über die unix zeitstempel funktionen

time()
mktime()
getdate()

sollten die Begriffe sein die du in der php manual nachschlagen kannst.

Als erstes solltest du du 0:00:00 Uhr am Montag der Aktuellen Woche anfangen. Wenn du dazu den unix zeitstempel hast ist der erste Schritt getan.
Um nun in die nächste Woche zu kommen musst du dann einfach zum unix zeitstempel eine Woche addieren.
Der Unix Zeitstempel ist in Sekunden, also wäre eine Woche 60*60*24*7.
 
ja klar du erstellst eine schleife und legst die daten in einem array ab, zb kalenderwochen für die kommenden 2 jahre ... das hieße dann 52x2

PHP:
$anzahlwochen = 52*2-1; // 52 wochen hat ein jahr, kommende 2 jahre ... - 1 da wir mit 0 anfangen

$start = ; // den montag dieser woche als unix zeitstempel hier rein

$einewoche = ; // anzahl der sekunden einer woche hier rein

$start = $start - $einewoche; // damit wir die aktuelle woche mit ins array bekommen einfach eine woche zurückdrehen

 // nun kann es los gehen
for($i=0;$i<=$anzahlwochen;$i++){ //zähler i startet bei 0, weitermachen solange kleinergleich wochenanzahl, in jeder runde eins dazu

// hier rechnest du jedes mal auf die letze woche eine woche drauf und machst dir ein array in der form
$wochenkalender[$i] = ...
}

//am ende hast du dann ein array mit 
$wochenkalender[0] = ...
$wochenkalender[1] = ...
$wochenkalender[2] = ...

je nachdem wo du deine daten dann verarbeitest holst du dir die zeitstempel aus dem array, machst daraus ein datum oder was auch immer, der letzte tag der woche ergibt sich ja allein

mehr hilfe brauchst du echt nicht, nun einfach mal basteln und die zeitfunktionen im php manual anschauen, so schwer ist das nicht
 
Datumsgeschichten in PHP sind immer ein wenig heikel.
Die addierung von Sekunden zum Timestamp kann ggf zu Prblemen mit Winter und Sommerzeit führen, das date('W') leifert nicht die Wochennummer die wir uns wünschen etc.

Darum hier eine Lösung falls man keine fremde API einbinden will.
PHP:
<?php
    setlocale(LC_TIME, 'de_DE', 'deu_deu');  
    $today = time();
    $yearend = mkdate(12, 31, date('Y'));
    
    $monday = strtotime("last Monday", $today);
    while ($monday <= $yearend){
        $date = new stdClass();
        $date->nr = getWeekNr($monday);
        $date->monday = $monday;
        $date->mondayStr = strftime("%x", $monday); 
        $date->sunday = strtotime("next Sunday", $monday);
        $date->sundayStr = strftime("%x", $date->sunday);
        $weeks[] = $date;
        $monday = strtotime("+1 week", $monday);         
    } 
    
    //Testausgabe
    foreach($weeks as $week){
        echo "{$week->nr}: {$week->mondayStr} bis {$week->sundayStr}<br />\n";
    }

    /**
     * create a date without time
     * @param int $month
     * @param int $day
     * @param int $year
     * @return timestamp
     */
    function mkdate($month, $day, $year){return mktime(0, 0, 0, $month, $day, $year);}
    
    
    /**
     * date('W') liefert für uns die falsche Wochennummer. Wir wollen nach ISO 8601:1988 
     * (erste Woche = Woche mint mindestens 4 Tage des neuen Jahres 
     * @param timestamp $date
     * @return int
     */
    function getWeekNr($date){
        //Windows kann icht alle Formatierbefehle. darum muss die Woche nach ISO 8601:1988 format anderst hergeholt werden
        //Version für Windows:
        if (stristr(PHP_OS, "win")<>false){
            return getWeekNumber(date('j', $date), date('n', $date), date('Y', $date));
        } else {
        //Version für Unix:
            return (Integer) strftime('%V', $date);
        }
    }

    // http://theserverpages.com/php/manual/en/function.strftime.php
    // Get the week number in ISO 8601:1988 format
    // This helsp when %V is not working on your Win32 machine
    function getWeekNumber($day, $month, $year) {
     $week = strftime("%W", mktime(0, 0, 0, $month, $day, $year));
     $yearBeginWeekDay = strftime("%w", mktime(0, 0, 0, 1, 1, $year));
     $yearEndWeekDay  = strftime("%w", mktime(0, 0, 0, 12, 31, $year));
     // make the checks for the year beginning
     if($yearBeginWeekDay > 0 && $yearBeginWeekDay < 5) {
      // First week of the year begins during Monday-Thursday.
      // Currently first week is 0, so all weeks should be incremented by one
      $week++;
     } else if($week == 0) {
      // First week of the year begins during Friday-Sunday.
      // First week should be 53, and other weeks should remain as they are
      $week = 53;
     }
     // make the checks for the year end, these only apply to the weak 53
     if($week == 53 && $yearEndWeekDay > 0 && $yearEndWeekDay < 5) {
      // Currently the last week of the year is week 53.
      // Last week of the year begins during Friday-Sunday
      // Last week should be week 1
      $week = 1;
     }
     // return the correct ISO 8601:1988 week (in two digit format)
     return( substr('0'. $week, -2) );
    }
?>
 
Vielen Dank für die hilfreichen Antworten. Zend Date ist mir bekannt, allerdings wollte ich gerne auf das einbinden von Zend verzichten(benutze als Framework Symfony und möchte auch aus Lernzwecken soviel wie möglich selbst machen)

Ihr habt mir sehr geholfen!
 
Hallo,

obige Ersatz-Funktion funktioniert so nicht richtig. Sie zeigt für den 01.01.2011 zum Beispiel KW53 an, obwohl es KW52 sein müsste.

Falls eine Verbindung zu mysql besteht, ist das hier eine verbesserte Version:

function getWeekNumber($day, $month, $year)
{
//MySQL KANN ES :)
$abfrage = "SELECT YEARWEEK('$year-$month-$day', 3) AS erg";
$ergebnis = mysql_query($abfrage);
while($zeile = mysql_fetch_object($ergebnis))
return substr($zeile->erg, -2);
}

Gruß
 
Mit was für einem Systerm arbeitest du? bei meinem Windows Vista und XAMPP mit PHP 5.2 funktioniert es richtig.
Währe interessant zu wissen mit welcher Konstelation es nicht geht.
 
Jetzt nach fast 12 Jahren habe ich Yaslaw für eine Version ohne mkdate Funktion gebeten.
Das Plugin Sourcerer das ich in Joomla 3 benutzte gibt eine Fehlermeldung ("CALL TO UNDEFINED FUNCTION MKDATE()") raus.
Yaslaw schrib mir dass diese Funktion eine "eigene" Funktion ist - UDF: User defined Function und scheinbar Sourcerer kann diese user defined functions nicht umsetzen.
Deswegen gab er mir, für die PHP Version 7.4 diese zwei Versionen:
Code:
<?php
    setlocale(LC_TIME, 'de_DE', 'deu_deu');
    
    $today = new DateTime();
    $today->setTime(0, 0);
    
    $yearend = new DateTime($today->format('Y-12-31'));

    if($today->format('w') == '1'){
        $monday = clone $today;
    }else{
        $monday = (clone $today)->add(DateInterval::createFromDateString('last monday'));
    }
    $sunday = (clone $monday)->add(new DateInterval('P6D'));

    while ($monday <= $yearend){
        echo("{$monday->format('W')}: {$monday->format('d.m.Y')} bis {$sunday->format('d.m.Y')}<br />\n");
        $monday->modify('+1 week');
        $sunday->modify('+1 week');
    }   
?>
und
Code:
<?php
    setlocale(LC_TIME, 'de_DE', 'deu_deu');

    //Heute definieren. Als reines Datum ohne Uhrzeit
    $today = (new DateTime())->setTime(0, 0);

    //Montag und Sonntag der aktuellen Woche
    $monday = (clone $today)->modify('Monday this week');
    $sunday = (clone $today)->modify('Sunday this week');

    //Schleife solange der Montag im aktuellen Jahr ist
    while ($monday->format('Y') <= $today->format('Y')){
        //Wochennummer, Montag und Sonntag ausgeben
        echo("{$monday->format('W')}: {$monday->format('d.m.Y')} bis {$sunday->format('d.m.Y')}<br />\n");
        //Moteg und Sonntag um eine Woche verschieben
        $monday->modify('+1 week');
        $sunday->modify('+1 week');
    }   
?>

Ich danke ihm sehr herzlich und weil ich die Ergebnisse des Codes nicht nur für ein Jahr bräuchte sondern bis Ende des nächsten Jahres, habe ich nach einige Recherchen in Internet seinen ersten Code ein bißchen geändert:
Code:
<?php
    setlocale(LC_TIME, 'de_DE', 'deu_deu');
    
    $today = new DateTime();
    $today->setTime(0, 0);
    
    $yearend = new DateTime('last day of December this year +1 years');

    if($today->format('w') == '1'){
        $monday = clone $today;
    }else{
        $monday = (clone $today)->add(DateInterval::createFromDateString('last monday'));
    }
    $sunday = (clone $monday)->add(new DateInterval('P6D'));

    while ($monday <= $yearend){
        echo("{$monday->format('W')}: {$monday->format('d.m.Y')} bis {$sunday->format('d.m.Y')}<br />\n");
        $monday->modify('+1 week');
        $sunday->modify('+1 week');
    }
?>

Nochmals Danke!
 
Zurück