date("w") rückwärts
wunderBAR
- php
Hallo Forum,
der Aufruf date("w") gibt mir die aktuelle ISO-Woche zurück.
Mein Bestreben ist es, das ganze umzudrehen. Ich habe die Kalenderwoche (auch ISO), und möchte damit den Range der KW ermitteln.
Ewiges Herumprobieren hat mich letztendlich zu diesem Vorgehen geführt:
Die Kalenderwoche ist beispielsweise 52 (das wäre die jetzige Woche). 52 Wochen haben 52*7=364 Tage. Das heißt nun aber nicht, dass KW52 am 364 Tag des Jahres endet. Man muss die Differenz zwischen dem 1.1. des jeweiligen Jahres und dem Sonntag vor Woche 1 abziehen. In diesem Jahr wäre das 4 (Donnerstag (1.1.2009) bis Sonntag (4.1.2009)). Nun kommt man auf den 364-4=360sten Tag des Jahres. Und siehe da, das ist der 27.12.2009, der Sonntag an dem die KW52 endet. Den Montag dazu herauszufinden ist ein Kinderspiel.
Das wäre dann folgender Code:
$stt_sonntag = ($_SESSION['kw'] * 7) - (7 - date("w", strtotime($_SESSION['year']."-01-01")));
Funktioniert im Jahr 2009 tadellos und zufriedenstellend. Ab Woche 53 im Jahr 2009 macht der Code allerdings nicht mehr mit, und ich habe absolut keine Ahnung warum. Das dürfte doch im Jahr 2010 auch klappen.
Wahrscheinlich ist der Fehler so klein, dass ich ihn schon nicht mehr sehe.
MfG
wunderBAR
Hi,
Und siehe da, das ist der 27.12.2009, der Sonntag an dem die KW52 endet.
Für PHP *beginnt* die Kalenderwoche mit dem Sonntag, dem null-ten Tag der Woche.
$stt_sonntag = ($_SESSION['kw'] * 7) - (7 - date("w", strtotime($_SESSION['year']."-01-01")));
strtotime kann auch mit Angaben wie '+17 weeks' oder '-3 days' rechnen.
~~~php
$firstOfYear = strtotime('2009-01-01');
$calendarWeek = '52';
$beginnCalenderWeek = strtotime('+'.$calendarWeek.' weeks -'.date('w', $firstOfYear).' days', $firstOfYear);
echo date('r', $beginnCalenderWeek);
MfG ChrisB
Hi, danke für deine Hilfe.
Für PHP *beginnt* die Kalenderwoche mit dem Sonntag, dem null-ten Tag der Woche.
Ja, darüber bin ich auch schon gestolpert. Nun bin ich mir unsicher, ob das Datum, das ich für den Sonntag herausbekomme, der Wochenanfang ist, oder doch das Ende der Woche.
strtotime kann auch mit Angaben wie '+17 weeks' oder '-3 days' rechnen.
Ja das weiß ich. Habe es damit auch schon probiert.
$firstOfYear = strtotime('2009-01-01');
$calendarWeek = '52';
$beginnCalenderWeek = strtotime('+'.$calendarWeek.' weeks -'.date('w', $firstOfYear).' days', $firstOfYear);
echo date('r', $beginnCalenderWeek);
Mit diesem Code bekomme ich das gleiche Ergebnis wie mit meinem. Die KW53 im Jahr 2009 ist dann identisch mit KW1 in 2010. Im Prinzip macht dein Code auch nichts anderes als meiner. Ich habe es auch schon mit mktime probiert. Dessen Parameter kann man auch ohne Probleme justieren: mktime(0,0,0,1,1+($\_SESSION['kw']\*7),$\_SESSION['year']). Aber das hat auch dasselbe Ergebnis: KW53/2009 = KW1/2010.
Ich komme hier einfach nicht weiter.
Lg
wunderBAR
Hi,
Mit diesem Code bekomme ich das gleiche Ergebnis wie mit meinem. Die KW53 im Jahr 2009 ist dann identisch mit KW1 in 2010.
Ja hat denn das Jahr 2009 überhaupt 53 Kalendarwochen?
Ansonsten hätten wir hier einfach nur wieder mal den Fall, dass die Datumsfunktionen „Überläufe” teilweise stillschweigend korrigieren.
MfG ChrisB
moin,
Mit diesem Code bekomme ich das gleiche Ergebnis wie mit meinem. Die KW53 im Jahr 2009 ist dann identisch mit KW1 in 2010.
Ja hat denn das Jahr 2009 überhaupt 53 Kalendarwochen?
Selbstverständlich. Nach DIN 1355 (Suchbegriff). Das Jahr 2009 beginnt mit einem Donnerstag.
Und wie die KW nach DIN 1355 berechnet wird, steht auf meiner WebSite.
Schöne Grüße,
Horst Wetterstein
Hi
Ja hat denn das Jahr 2009 überhaupt 53 Kalendarwochen?
Ja. Ich muss mich auf date("w") verlassen, denn das gibt mir die ISO-Woche zurück.
Trotzdem habe ich noch keine Lösung gefunden. Ich habe wirklich ungern Lust, die komplette ISO-Norm zu implementieren, wenn date("w") diese schon berücksichtigt...
Diese Grafik, die ich erzeugt habe, demonstriert das Problem sehr deutlich. KW53 ragt ins Jahr 2010. Nach dieser Grafik habe ich auch meine Vorgehensweise (siehe OT) erstellt. Aber die scheint wohl nicht immer zu klappen...
Gruß
wunderBAR
Hi
Ja. Ich muss mich auf date("w") verlassen, denn das gibt mir die ISO-Woche zurück.
Da bin ich mir nicht so sicher.
[..] Ich habe wirklich ungern Lust, die komplette ISO-Norm zu implementieren, wenn date("w") diese schon berücksichtigt...
So schlimm ist das nun nicht. Bestimme den Wochentag (0..6) vom 1.1. und vom 31.12. des Jahres. Damit hast Du alles:
Der Rest ist bischen Tipparbeit.
Hotti
Hi
Ja. Ich muss mich auf date("w") verlassen, denn das gibt mir die ISO-Woche zurück.
Da bin ich mir nicht so sicher.
Laut PHP aber schon.
Gruß
wunderBAR
Hi,
Ja. Ich muss mich auf date("w") verlassen, denn das gibt mir die ISO-Woche zurück.
Da bin ich mir nicht so sicher.
Laut PHP aber schon.
date_default_timezone_set('Europe/Paris');
$t = time();
print date('W', $t);
Liefert mir eine 52. Das ist jedoch unvollständig(*), zur Angabe einer KW gehört grundsätzlich das Jahr, wie Deine Grafik das auch zeigt: Die letzte KW eines Jahres kann in das neue Jahr fallen. Genauso kann die erste KW eines Jahres auch im Jahr vorher beginnen.
(*)Daher bin ich mit nicht sicher.
Hotti
Hi,
date_default_timezone_set('Europe/Paris');
$t = time();
print date('W', $t);
>
> Liefert mir eine 52. Das ist jedoch unvollständig(\*),
Wenn du nur W ausgeben lässt, bekommst du auch nur W. Wenn du das Jahr auch noch haben willst, dann nehme noch Y in den Formatstring mit auf.
MfG ChrisB
--
“Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
Hi,
date_default_timezone_set('Europe/Paris');
$t = time();
print date('W', $t);
> >
> > Liefert mir eine 52. Das ist jedoch unvollständig(\*),
>
> Wenn du nur W ausgeben lässt, bekommst du auch nur W. Wenn du das Jahr auch noch haben willst, dann nehme noch Y in den Formatstring mit auf.
Freilich ;-)
Aber umgedreht soll es ja sein: Aus 'W' die Tage machen. Und das allein geht nicht mit Formatierungen, da musst Du schon ein bischen rechnen. Ich rechne das über den julianischen Tag. Zuerst rechne ich die Tagesnummer des ersten Tages der ersten KW des Jahres aus. Dann multipliziere ich die gewünschte KW mit 7 und addiere das auf die Tagesnummer des ersten Tages der ersten KW. Damit erhalte ich den Tag, an dem die gesuchte KW beginnt.
Hotti
--
Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
Hi,
Aber umgedreht soll es ja sein: Aus 'W' die Tage machen. Und das allein geht nicht mit Formatierungen, da musst Du schon ein bischen rechnen.
Das ist klar.
Aber bezogen auf das von dir gebrachte Beispiel war die Aussage sinnlos.
MfG ChrisB
Hi,
Aber umgedreht soll es ja sein: Aus 'W' die Tage machen. Und das allein geht nicht mit Formatierungen, da musst Du schon ein bischen rechnen.
Das ist klar.
Aber bezogen auf das von dir gebrachte Beispiel war die Aussage sinnlos.
Mag sein. Schau ins Jahr 2011, da wird das vielleicht deutlicher:
der 1.1.2011 hat KW 52 und
der 31.12.2011 hat auch KW 52.
Jedoch: KW 52 gehört zum Jahr 2010 was den 1.1. betrifft. 'W' ist lediglich eine Formatierung des unixtimestamps. Diese Formatierung ist nicht umkehrbar. Hast Du das verstanden?
Hotti
Hi,
'W' ist lediglich eine Formatierung des unixtimestamps.
Ja - und mehr als das zeigte dein Beispiel nicht. Und damit war deine Aussage in Bezug auf dein Beispiel sinnfrei -
Hast Du das verstanden?
Diese Formatierung ist nicht umkehrbar.
Darüber besteht gar kein Diskussionsbedarf - das war allen Beteiligten von Anfang an klar.
MfG ChrisB
Darüber besteht gar kein Diskussionsbedarf - das war allen Beteiligten von Anfang an klar.
So viel Diskussion für ein Einzeiler :)
Darüber besteht gar kein Diskussionsbedarf - das war allen Beteiligten von Anfang an klar.
So viel Diskussion für ein Einzeiler :)
Wie jetzt, hast Du hier auch was zu sagen ;-)
SCNR;
Horst Radauplättchen
Wie jetzt, hast Du hier auch was zu sagen ;-)
Ich sage nichts :), das war mehr eine Feststellung.
SCNR;
Horst Radauplättchen
Ich würde als erstes das Datum des ersten Tages der ersten KW bestimmen und von da ausgehend weitermachen.
Nun kommt man auf den 364-4=360sten Tag des Jahres. Und siehe da, das ist der 27.12.2009
Wie hast du das Datum bestimmt?
Funktioniert im Jahr 2009 tadellos und zufriedenstellend. Ab Woche 53 im Jahr 2009 macht der Code allerdings nicht mehr mit
Wie äußert sich das?
Hallo Forum,
ich habe die Lösung zu dem Problem gefunden. Es war aber wirklich nicht einfach und mit vielen vielen Notizzetteln und Gegenüberstellungen der Jahre verbunden.
Damit ihr und diejenigen, die diesen Thread später im Archiv finden, auch etwas davon habt, beschreibe ich euch ausführlich, wie ihr vorgehen müsst.
Zuerst muss man unterscheiden, ob ein Jahr 52 oder 53 Wochen hat. Denn dann berechnen sich die Daten GANZ(!) anders. Und hierbei tut sich schon das erste Problem auf - wie macht man das?
Wenn man genau hinschaut, sieht man, dass der 4.1. IMMER in KW1 liegt. Demnach kann man mit dem Tag davor, also dem 3.1., Unfug treiben. Denn entweder liegt der in KW1, oder nicht. Wenn der 3.1. also in KW1 liegt, hat das *vorhergehende* Jahr 52 Wochen. Ansonsten 53.
function get_max_kw_a_year($year)
{
$day = date("W", mktime(0,0,0,1,3,$year+1));
if($day==1)
return 52;
else
return 53;
}
Mit dem Rückgabewert dieser Funktion wird nun unterschieden, ob ein Jahr 52 oder 53 Wochen hat. Im Moment ist es belanglos, ob die KW53 noch ins nächste Jahr hineinhängt. Denn es geht ja nur darum, die Wochenanzahl eines Jahres, die dem zugeordnet sind, zu bekommen.
Die Vorgehensweise bei 53 Wochen ist einfach. Man nehme die Anzahl der Tage der gewünschten KW. 5 Wochen haben 5*7=35 Tage. Man muss nur noch die Differenz zwischen dem 1.1 und dem darauffolgenden Sonntag subtrahieren. Im Jahr 2009 sind das 4 Tage (nämlich Donnerstag 1.1.2009, Freitag 2.1.2009, Samstag 3.1.2009 und Sonntag 4.1.2009). Man bekommt dann den Tag, an dem die gewünschte KW endet (Sonntag).
Demnach bei KW5 in 2009:
5 * 7 = 35
35 - 4 = 31
Ein Blick in den Kalender zeigt, dass KW5 /2009 am 1.2.2009 endet. Man erkennt, dass man die gewonnen Zahl (31) nur zum 1.1.2009 hinzuaddieren muss.
if(get_max_kw_a_year($_SESSION['year']) == 53)
{
$sonntag = $_SESSION['kw'] * 7;
$sonntag = $sonntag - (7 - date("w", strtotime(($_SESSION['year']-1)."-12-31")));
$sonntag = $sonntag * (24*60*60);
$sonntag = $sonntag + strtotime($_SESSION['year']."-01-01");
}
(Ich erstelle hier einen Timestamp, da ich den später noch brauche.)
Ganz anders sieht es aus, wen ein Jahr 52 Wochen hat.
Ich bin hier so vorgegangen, dass ich die KWs schon einmal hinzuaddiere. Danach entscheide ich erst, wie viele Tage noch auf den gewünschten Sonntag fehlen. Oder welche zuviel sind. Denn auch das gibt es:
2010 +2 Tage
2011 +1 Tag
2012 +-0
2013 -2 Tage
2014 -3 Tage
2016 +2 Tage
Also braucht man nun einen Indikator, der mir "addieren" oder "subtrahieren" sagt. Also musste ich wieder den Kalender zur Hand nehmen und vergleichen. In den Jahren von 1995 bis 2025 mit 52 KWs fiel auf, dass man addieren muss, wenn der 1.1. des Jahres NICHT in der ISO-KW 1 liegt. Subtrahieren muss man, wenn das nicht der Fall ist. Gar nichts addieren oder subtrahieren muss man, wenn der 1.1. ein Sonntag ist.
Jetzt wissen wir, ob wir addieren oder subtrahieren müssen. Aber *was* müssen wir eigentlich addieren/subtrahieren? Addieren müssen wir, wie oben, die Differenz vom 1.1. zum nächsten Sonntag. Subtrahiert werden muss nur der Tag der Woche des 1.1. (Sonntag = 0, Montag = 1, etc ...).
So entsteht dann der else-Teil:
else
{
$ber=$_SESSION['year']."-01-01 +".$_SESSION['kw']." weeks";
if(date("w", $_SESSION['year']."-01-01")!=0)
{
if(date("W",strtotime($_SESSION['year']."-01-01"))!=1)
$ber.=" +".(7 - (date("w", strtotime($_SESSION['year']."-01-01"))))." days";
else
$ber.=" -".date("w", strtotime($_SESSION['year']."-01-01"))." days";
}
$sonntag = strtotime($ber);
}
Für den Montag müssen noch 6 Tage abgezogen werden:
$montag = $sonntag -(24*60*60 * 6);
Und "schon" haben wir $montag und $sonntag zur angegebenen KW und dem angegebenen Jahr. Wenn ihr jetzt noch irgendwo Denkfehler seht, oder noch den ein oder anderen Fall, den dieser Code nicht mit macht, bin ich euch sehr verbunden, wenn ihr es noch schreiben könntet.
Liebe Grüße
wunderBAR