Open mosbth opened 2 years ago
Innan jag själv hade börjat koda så hade jag plockat fram ett par grundvärden, ungefär som ovan så förväntar jag mig att jag behöver leta reda på första måndagen och sista söndagen på något sätt. Koden som löser det kan se rätt olik ut, men man bör på något sätt komma fram till något liknande som jag visar i bilden här, innan man sätter igång med loopandet och utskriften av kalendern.
Det kan nu vara en tanke att utgå från den första timestampen och loopa fram + 1 day
i taget och "byta rad" varje söndag.
<tr>
<td><?= $weekNum ?></td>
</tr>
Om man börjar med någon enkel konstruktion så kanske saker faller på plats allt eftersom?
Att skissa sin problemlösning med pseudokod kan vara ett bra alternativ att snabbt få ned en grov plan på en lösning. Sedan kan man ta kodbitarna steg för steg.
Här är en variant av pseudokod som är en skiss på en loopkonstruktion för fotokalendern. Det kan finnas flera andra varianter av giltiga lösningar, så försök att problemlösa på egen hand.
firstDay = find first day in month, use it to find the date of the first Monday in the calendar
lastDay = find the last day in the month and use it to find the date of the last Sunday in the calendar
<table><tr><th>...</tr>
currentDay = firstDay
while (currentDay not passed the lastDay) {
<tr>
Get weekNum from currentDay
<td>weekNum
for (i between 1 to 7) {
Get all details for the currentDay, save in variables
<td>Print details on this day
currentDay + 1 day
}
</tr>
}
</table>
for
(hårdkoda antalet veckor)Jag klurade lite på hur man gör enklaste möjliga utskriften i loopen. Det handlar en del om problemlösning och veta vad man kan göra med sina datum. Här är pseudokod för en variant som troligen är enkelt att förstå. Lösningen utgår från att om man skriver ut 6 veckor så löser det alltid alla månader. Kanske är det en fullösning, men funkar det så löser det problemet och det är inget bekymmer om det kommer med en extra vecka.
Lösningen bygger på att man har kommit så här långt i sin kod och nu skall skriva ut vecka för vecka och det första man skriver ut är veckonumret.
$currentTimestamp = the timestamp of the first day
$numWeeks = 6;
for ($week = 0; $week < $numWeeks; $week++) {
// Start the table row
<tr>
// Get the current week number
$currentWeek = Use the current timestamp to get the week number
<td>$currentWeek
for ($i = 0; $i < 7; $i++) {
// Loop from monday to sunday, 7 days in one week
$currentDate = Get the current date from the current timestamp
<td>$currentDate
// Move timestamp one day forward
$currentDate = Create a date 'Y-m-d' from the current timestamp
$currentTimestamp = Use $currentDate . " + 1 day" to move the timestamp one day forward
}
// Close the table row
</tr>
}
Kanske är detta det enklaste sättet att lösa fotokalendern, att helt enkelt hårdkoda in att man skriver ut 6 veckor. På det viset slipper man iallafall att försöka klura ut hur man loopar fram till sista dagen och hur det villkoret skulle kunna se ut.
Om jag kodar enligt for-loopen ovan så blir mitt enda bekymmer att jag får en extra vecka. Men det gör inget. För min del blir resultatet så här när jag lyckats med loopen ovan.
Kanske kan jag lösa sista veckan med någon "fix" så jag hoppar ur loopen om det blir en vecka för mycket, men det kan man ta som överkurs.
do-while
Jag fortsatte klura lite på hur man gör en snyggare lösning med while
och där är ju trixet vilket villkor man skall ha i loopen. Det är faktiskt inte uppenbart, iallafall om man är ny på programmering.
Är man ny så kan man nog köra på for-loopen ovan.
Men, om vi skall försöka hitta en snyggare lösning så kan man fundera vidare på vilket villkor man kan ha som löser att man skriver ut rätt antal veckor. Jag gissar att flera av er löser det på något klurigt sätt.
För min egen del så valde jag att använda en do-while
loop. Den är ungefär likadan som en while
loop, men villkoret ligger i slutet och skillnaden är att man alltid går ett varv i loopen, innan man testar villkoret. I mitt fall gjorde det att jag kunde köra loopen ända fram till $lastDate
som i mitt fall var formatterat enligt 2023-01-01
i mitt exemepl med december månad.
Här är en grov pseudokod för en do-while
lösning.
// Loop from first day to last day and print each day in a <td>
$currentTimestamp = Timestamp of first day
$currentDate = null;
do {
// Start the table row
// Get the current week number
for ($i = 0; $i < 7; $i++) {
// Loop from monday to sunday, 7 days in one week
// Move one day forward
$currentDate = 'Y-m-d' according to $currentTimestamp
$currentTimestamp = $currentday + 1 day
}
// Close the table row
} while ($currentDate != $lastDate);
Föredelen med denna lösningen, jämfört med hårdkoda 6 veckor, är att min fotokalender innehåller exakt de veckorna jag vill. Utmaningen är att klura ut villkoret för hur länge man skall loopa i while-loopen, eller som jag gjore, en do-while-loop.
Så här ser min kalender ut nu.
En sak som är lite svår att läsa ut från manualen är hur man kan göra datumberäkningar med funktionen strtotime()
och strängar utifrån en timestamp. Kika på följande exempel som användes i en kmom03 zoom.
$firstDayInWeek = date('Y-m-d', strtotime("Monday this week", $timestamp));
$lastDayInWeek = date('Y-m-d', strtotime("Sunday this week", $timestamp));
$firstDayInMonth = date('Y-m-d', strtotime("first day of this month", $timestamp));
$lastDayInMonth = date('Y-m-d', strtotime("last day of this month", $timestamp));
$previousMonth = date('Y-m-d', strtotime("first day of previous month", $timestamp));
$nextMonth = date('Y-m-d', strtotime("first day of next month", $timestamp));
Ibland behöver man leka runt för att hitta rätt startdatum, då kan man skriva små enkla testprogram som tar fram de värden man behöver. Här är ett sådant testprogram.
https://github.com/dbwebb-se/webtec/blob/main/example/sample/date.php
Jag började rätta i kmom04 och tog ett par bilder på de första rättningarna och deras fotokalendrar. https://imgur.com/a/8vMRVh3
I Discord har det förekommit ett par tips om hur man kan börja tänka när man jobbar med kalendern, här är ett av de tipsen.