Hei,
Oli pakko tulla tänne taas tilittämään ongelmaani ja pyytämään apua. Luulin kerrankin tehneeni n. puoli vuotta sitten toimivan viikkokalenterin mutta ei. Kas kummaa kun vuosi alkoi lähestymään loppuaan niin huomasin itselleni taas uuden asian. Sen lisäksi, että vuodessa voi olla myös 53 viikkoa voi vuodessa olla kaksi samaa viikkoa. Joille tämä tuli yllätyksenä ( minulle ) niin katsokaa kalenterista. Tämä vuosi todellakin alkaa ja loppuu viikkoon 1. Tässäpä se ongelmani sitten onkin.
Seuraavalla koodin pätkällä selaan viikkoja eteen ja taaksepäin, mutta entäpä jos tulee edellämainittu ongelma vastaan. Miten sen voisin ohittaa.
<?php $toimenpide = $_REQUEST['toimenpide']; $this->ViikkojaVuodessa = $this->ViikkojaVuodessa(); if(empty($_REQUEST['viikko'])){ $this->Viikko = date('W'); } else { $haettavaViikko = intval($_REQUEST['viikko']); $this->Viikko = $haettavaViikko; if($toimenpide == 'taaksepain') { $this->Viikko = ($haettavaViikko - 1); if($this->Viikko == 0){ $this->Vuosi = (intval($_REQUEST['vuosi']) - 1); /* Tässä suoritetaan viikkojen laskeminen */ $aikaleima = mktime(0, 0, 0, 12, 31, $this->Vuosi); $viikkoja = intval(date('W', $aikaleima)); if($viikkoja == 1) { $aikaleima = mktime(0, 0, 0, 12, 27, $this->Vuosi); $viikkoja = intval(date('W', $aikaleima)); } /* Tässä palautetaan lopullinen arvo viikoille */ $this->Viikko = $viikkoja; } } if($toimenpide == 'eteenpain') { $this->Viikko = ($haettavaViikko + 1); if($this->Viikko > $this->ViikkojaVuodessa) { $this->Vuosi = (intval($_REQUEST['vuosi']) + 1); $this->Viikko = 1; } } } ?>
Aloita viikkojen laskeminen aikaleiman alusta, mutta näytä käyttäjälle vain 1-53. Tällöin saat ns. uniikin viikkonumeron jokaiselle mahdolliselle viikolle.
Älä siis yritä laskea päivämäärää viikkonumeron mukaan, vaan laske viikkonumero päivämäärän mukaan.
Tällöin ei tule ongelmia.
Kehtaatko pistää vähän esimerkkiä, miten se tuolla mktime:lla tapahtuu.
viikko(päivä jonka viikon haluat tietää) { return ((vuoden eka viikonpäivä, maanantai = 0) + (päivä jonka viikon haluat tietää)) / 7 } // Vuodessa 53 viikkoa, ensimmäinen = 0 jos(viikko(365) == 52){ viikko = viikko(päivä) } // Vuodessa 52 viikkoa, viikkoa numero 0 ei siis ole olemassa muuten{ viikko = viikko(päivä) + 1 }
Minä ainakin säilyttäisin aikaleimaa ihan vain aikaleimana ja hoitaisin laskut sekunneissa. Alussa aikaleiman voisi alustaa johonkin viikonvaihteeseen, ja muutettaessa sitä tietenkin muutettaisiin tasapäivien tai -viikkojen verran, vaikka sekunneista onkin puhe. Näyttämistä varten saa kyllä tiedot riittävän helposti ulos:
Kannattaa säilyttää ohjelman sisällä tietoa siinä muodossa, jossa sitä on helpointa käsitellä, ja nähdä vähän ylimääräistä vaivaa mieluummin sitten käyttäjän kanssa kommunikoinnissa. Ohjelman logiikka mutkistuu usein aivan käsittämättömäksi, jos dataa yrittää säilyttää siinä epäloogisessa muodossa, jossa se pitää esittää käyttäjälle.
Mielelläni tuon aikaleiman säilyttäisinkin. Muuten tuossa ei ole minulle ongelmaa mutta juuri tuo tiedon tallentaminen on se mikä kusee. Tallennan tiedot viikon ja vuoden mukaan ja kas kummaa. Samalla vuodella onkin kaksi samaa viikkoa.
- Lisäys.
Periaatteessahan riittää, että kaivasen jotenkin tuon kuukauden siihen mukaan ja tallennan senkin kantaan. Mutta eipä sekään taida onnistua, kun enhän minä tiedä missä kuukaudessa käyttäjä seikkailee. Sitäkään ei voi viikosta laskea, kun niitähän voipi olla se kaksi samassa vuodessa.
Mutta pointtini olikin, että älä tallenna viikkoa ja vuotta vaan tallenna aikaleima, niin homma ei kuse. Älä missään vaiheessa säilytä missään viikkoa ja vuotta, säilytä vain aikaleimaa ja muuta se viikoksi ja vuodeksi tasan sillä hetkellä, kun pitää tulostaa se viikon numero ja vuosi. Jos ihan välttämättä haluat viikoilla pelleillä, niin käytä sitten edes "absoluuttista" viikkonumeroa, $aikaleima / (60*60*24*7)
. Näin saat viikon "numerosta" laskettua viikon alun aikaleiman, josta saat selville vuoden, kuukauden ja viikon todellisen numeron date-funktiolla.
Näinhän se homma tietenkin toimisi.
Voipi olla, että pelleilen vielä hetken. Tämä tominnallisuus on muutenkin hieman karu, eikä niin käyttäjäystävällinen kuin kuuluisi. Heti ajan tullen teen uuden, joten en viitsisi rueta kovin pitkää koodirimpsua kirjoittamaan tämän korjaamiseksi. Lähettämäni pätkä on vain osa kokonaisuutta ja joutuisin muuttamaan liian monta paikkaa tuolle järkevämmälle vaihtoehdolle.
Mutta pidän tuon järkevämmän vaihtoehdon mielessä, kun rupean uutta tekemään.
Tuota en nyt oikein tajunnut/saanut toimimaan. Pitää palata oppaiden ääreen.
$aikaleima / (60*60*24*7).
Vasta_alkaja kirjoitti:
Näinhän se homma tietenkin toimisi.
Tuota en nyt oikein tajunnut/saanut toimimaan. Pitää palata oppaiden ääreen.
$aikaleima / (60*60*24*7).
Tässä siis juuri muutetaan sekunnit viikoiksi (perus matematiikkaa), jossa viikon numero on laskettu php:n käyttämän aikalaskurin alusta asti (vuodesta 1970).
Näin kun lasketaan, niin ei ole väliä onko vuoden alussa ja lopussa sama viikon numero (1).
date() -funktiolla saa helposti aikaleimasta tulostettua viikon numeron, tätäkään ei siis kannata käyttää kuin käyttäjälle tulosteena. Älä siis tallenna viikon numero mihinkään, kuten olet huomannu, se ei ole tarkka aika.
Miten tekisin sellaisen toiminnon forsilumakalla, että viikko alkaisi ja loppuisi, niinkuin se on kalenterissakin.
1,2,3,4,5 jne.. Kalenteria kun tarkemmin katsoin, niin näkyi tuo vuosikin voivan alkaa viikosta 53.
Tietenkin yksinkertaisimmillaan sen voisi tehdä vain niin, että on kiinteäsi viikot 1-53, mutta olisihan se tietenkin hienompi jos menisi ihan oikein. esim
53,1,2,3 jne..
1. Tee mktimella vuoden alun ja lopun aikaleimat.
2. Siirrä alkuleimaa taaksepäin viikonpäivän mukaan viikon ensimmäiseen päivään.
3. Siirrä loppuleimaa eteenpäin viikonpäivän mukaan seuraavan viikon ensimmäiseen päivään.
Kas näin.
<?php $vuosi = 2008; # kohta 1 $alku = mktime(0, 0, 0, 1, 1, $vuosi); $loppu = mktime(0, 0, 0, 1, 1, $vuosi + 1); # kohdat 2 ja 3; nämä voisi tehdä silmukassakin (while (ei ole maanantai)) $alku = $alku - 24*60*60 * ((date("w", $alku) + 6) % 7); $loppu = $loppu + 24*60*60 * ((8 - date("w", $loppu)) % 7); # viikko kerrallaan for ($viikko = $alku; $viikko < $loppu; $viikko += 7*24*60*60) { echo "viikko ", date("W", $viikko), ": |"; # viikon päivät for ($paiva = $viikko; $paiva < $viikko + 7*24*60*60; $paiva += 24*60*60) { echo " ", date("d.m.", $paiva), " |"; } echo "\n"; } ?>
Kiitoksia tästä kovasti.
Aihe on jo aika vanha, joten et voi enää vastata siihen.