16. april 2007 - 21:04Der er
55 kommentarer og 1 løsning
Nedtæl ugenr og År
Hej eksperter
Jeg er ved at lave noget kalender agtigt værk hvor man kan navigere frem og tilbage i ugerne.
I min URL har jeg en year og en week, så man fx får:
pages.php?year=2007&week=16
Men hvis man nu står på year 2007 og week 1 og tæller en ned, hvordan får jeg den så til at springe et år og et ugenummer ned?
Jeg kunne jo snildt komme gennem det ved at trække 1 fra året og lave noget if der tjekker på at ugenr er 1 og hvis ja kunne den springe ned på uge 52.. Men nogle år er der jo 53 uger, hvordan gør man så?
Altså du kan bruge mktime() til at lave en dato på året! F.eks.: $myYear = '2006'; //2005, 2007 osv... $year = mktime(0,0,0,1,1,$myYear); echo 'Der er antal uger : ' . date('W',$year);
Jeg tror det ville være bedre at gå bort fra ugenumre og årstal i din url, istedet vil jeg anbefale at du bruger et relativt reference i forhold til idag....
Det 'fede' ved mktime() funktionen er at den kan lægge f.eks. 40 dage til en dato og så selv regne ud at måneden skifter og måske også året...eksempelvis..
Men johan hvad nu hvis jeg vil springe til en bestemt uge fx fra nogle select bokse hvor man vælger fx uge 3 år 2001.. Hvordan får jeg så den rigtige "var" værdi for netop den uge?
Nu ved jeg ikke hvad det hele skal bruges til, men hvis du laver den relativ ud i fremtiden (ligesom johan.o foreslår), så vil det ikke være muligt at benytte det samme link om ex 2 uger, da standard udgangspunkt-tiden har rykket sig.
Så hvis man skal kunne henvise til siden, så fungerer det vel ikke i praksis uden at komplicerer mere end højst nødvendigt (og lave alternative links - men så ryger idéen når man har to måder at hente sit resultat).
Jeg kan ikke se hvorfor mktime ikke kan benyttes sammen med year og en dato. Så man finder uge-nr. ud fra en dato, og når man klikker rundt i ugerne på siden, sætter man den til at linke til mandagen ugen efter. Skal man en uge frem, lægger man 7 dage til den aktuelle dato - og trækker fra når man skal tilbage.
Kan ikke lige gennemskue at det ikke skulle virke, men er lidt omtumlet i dag - har fået pillet lidt ved balance-nerven i mine ører i dag, hvis det siger nogen noget ;)
Koden jeg har ser PT ud, som nedenstående og virker fint.. Men jeg vil som jer andre, nok foretrække at få Year og Week frem i linien foroven, både for brugervenligheden og for mig selv, så man lettere kan gå tilbage i tiden, men hvordan? :)
Har lige skrevet et rigtig langt svar der gav det hele - men men men .. gode Gamle eksperten.dk loggede mig ud og automatisk ind - meeen glemte lige at tilføje det jeg havde skrevet. Du får en kort version uden så mange forklaringer: _________________________________________________
if (preg_match('/([\d]{4})/', $_GET['year'])&&preg_match('/([\d]{2})/', $_GET['day'])&&preg_match('/([\d]{2})/', $_GET['month'])) // DO YOU THING else // ERROR _________________________________________________
$this_week = mktime(0, 0, 0, $_GET['month'], $_GET['day'], $_GET['year']); echo "Denne uge er ".date("W", $this_week)." i år ".date("Y", $this_week); _________________________________________________
nixir.. Når man trykker på næste uge kommer der ikke et 0 med i month, hvilket resultere i at man ikke kan se noget pga. valideringen der forlanger to cifre..
Kan godt forstå hvor i vil hen, men er efterhånden ved at være mere lost i det her end da jeg startede :S
og igen.. Hvis jeg nu har to select bokse, hvor der i den ene er en række uge numre og i den anden en række ugenumre, så man derved kan springe til en bestemt uge. Hvordan skal jeg så beregne mig frem til den rigtige uge? :S
Sådan ... Det må du undskylde ... tanke-torsk ... Som sagt havde jeg lavet et længere svar, men det blev slettet - og så gider jeg ikke skrive det hele igen - du kan nok fornemme der var lidt mere guf på end det jeg sendte ;)
Om du vælger relative eller absolute værdier i din url er helt op til dig, begge dele kan fungere og begge dele har fordele og ulemper, er f.eks. links til bestemte perioder vigtige bør du vælge absolute værdier.
Jeg går ud fra at du mener at du har en select med uge numre og en select med årstal som så skal kunne frembringe den valgte uge i kalender form....
echo "<pre>Dit link er : dinside.php?day=".date("j", $oMandag)."&month=".date("n", $oMandag)."&year=".date("Y", $oMandag)."</pre>";
?>
For test formål er det lavet sådan at 'den' henter uge nummer og årstal fra url'en så kan du sikkert selv indarbejde funktionaliteten i din kode.
Princippet er at den 4. januar er altid, uanset årstal med i uge 1. Det medfører at den valgte uges nummer ganget med 7 og så tillagt 4 er det antal dage der er fra den 1. januar til en dag der med sikkerhed er i den valgte uge....det natal findes i denne linje..
$oDage=(($oUge-1)*7)+4;
Vores mål er at finde datoen for mandagen i det valgte ugenummer.
Nu har vi fundet en dag vi ved der er i den valgte uge, men vi ved ikke hvad dag det er, derfor skal vi finde ud af dagens nummer, det gør vi i denne linje..
..værd opmærksom på to ting. For det første '1' for januar og så ligger vi det tidligere fundne antal dage oveni og så finder mktime selv ud af det hvis måneden skifter. Dernæst brugen af "w", er ikke optimal da den returnere 0 hvis det er en søndag. Det er ikke optimalt da vi gerne vil have 7 for søndage, men da "w" er den eneste 'identifier' der er platform uafhængig har jeg valgt den. Hvis du kører PHP 5.1 eller højere kan du med fordel bruge "N" og så slette denne linje da den blot kompensere for 'søndags-problemet'..
if($oDagNr==0) { $oDagNr=7; }
..okay så så har vi et antal dage til en dag vi ved der i den uge vi vil vise, og vi ved hvilket nummer denne dag har, så ved at trække dagens nummer (-1) fra antallet af dage bør vi finde mandag i den uge vi vil vise..
..og lige en ting omkring mktime/date osv. det er vigtigt at huske at skudår og sommer-/vinter-tid kan medfører 'problemer/unøjagtigheder' hvis man begynder at 'gå ud fra' at en dag er (60*60*24) sekunder.
Det med den relative uge holder ikke i praksis - jeg er ked af at sige det. Hvis vi ser det ud fra et perfomance mæssigt synspunkt er den absolute date difination klart den bedste løsning.
Den vil aldrig kunne returnerer en forkert uge hvilket jeg synes er en lille fordel ;)
URL's kan benyttes uanset dato ... Sidder man på sitet fra kl 23.59 til kl 00.01, ja så vil man kunne opleve at scriptet går i kage. Noget registreres et forkert sted eller lign. Noget man for alt i verden ikke engang må lade være en teoretisk mulighed.
Her er noget nær den optimale kode til løsning af dit problem:
if (preg_match('/([\d]{4})/', $_GET['year'])&&preg_match('/([\d]{2})/', $_GET['day'])&&preg_match('/([\d]{2})/', $_GET['month'])) {
$nxt_ year bliver defineret i form.php, men bruges ikke da jeg lavede om i forhold til min første måde at lave det på ... udover det så vil den linie også fejle fordi "$nxt_ year" ikke er en gyldig variabel.
en anden lille ting ... Jeg tror måske du er nødt til at smide: $pre_week = 0; $this_week = date('W',$date); ... foran while(...) {
echo "<pre>Week number ".$week." contains the following days...</pre>";
for($i=0; $i<7; $i++) { echo "<pre>".date("l j. F Y", mktime(0, 0, 0, $month, $day+$i, $year))."</pre>"; }
echo "<pre>Og hvis du skal søge efter informationer i din database der passer i den viste uge kan du bruge følgende timestamps...</pre>";
echo "<pre>Start : ".mktime(0, 0, 0, $month, $day, $year)." som er ".date("l j. F Y H:i:s", mktime(0, 0, 0, $month, $day, $year))."</pre>"; echo "<pre>Slut : ".mktime(23, 59, 59, $month, $day+($i-1), $year)." som er ".date("l j. F Y H:i:s", mktime(23, 59, 59, $month, $day+($i-1), $year))."</pre>"; }
Det er sådan noget som Johans seneste indlæg at jeg søger, dog blandet sammen med det første i lavede med frem og tilbageknapper.
Altså man kommer ind på pages.php?viewtype=Week&year=2007&week=16
Man ser altså fra start af den uge man er i lige nu.
Man skal kunne navigere frem og tilbage i ugerne, ligesom de frem og tilbageknapper vi lavede tidligere. Og samtidig skal der oppe i det ene hjørne være et par selection-bokse den ene med ugenr og den anden med årstal, og så en "go" knap, så man altså kan navigere hurtigt til en uge der ligger nogle år tilbage eller fremme.
Det med at bruge en relativ værdi er som tidligere nævnt usikkert, og set ud fra et performance-synspunkt lidt mere krævende da man ikke blot kan lave et timestamp og trække en uge fra eller lægge en uge til - og så selvfå den til at finde ud af året etc... Det komplicerer noget unødigt.
Men det er klart du skal bruge det du bedst selv kan lide, da du sikkert vil klumre rundt i det andet (hvis du ikke helt forstår det).
--> nixir...der er vist ikke nogen der bruger relative værdier i denne tråd mere da haolan jo har gjort det klart at det ville 'han' gerne være fri for.
Jeg forsøger om jeg kan få fikset noget af det sammen i indtil videre har lavet og så vender jeg tilbage med min endelige løsning, samt pointudeling :)
Johan >> Nu udskriver jeg ikke en hel uge ligesom du gør i dit eksempel, hvilket jo betyder at jeg får et problem med $i i sætningen: mktime(23, 59, 59, $month, $day+($i-1), $year).
Hvad skal jeg smide ind i stedet for $i her, for alligevel at komme til slutningen af ugen, som du gør?
$oOutput.="<pre>Og hvis du skal søge efter informationer i din database der passer i den viste uge kan du bruge følgende timestamps...</pre>";
$oOutput.="<pre>Start : ".mktime(0, 0, 0, 1, $oDays, $year)." som er ".date("l j. F Y H:i:s", mktime(0, 0, 0, 1, $oDays, $year))."</pre>"; $oOutput.="<pre>Slut : ".mktime(23, 59, 59, 1, $oDays+6, $year)." som er ".date("l j. F Y H:i:s", mktime(23, 59, 59, 1, $oDays+6, $year))."</pre>";
Drop down boksene har jo en lille svaghed da de ikke er dynamiske..eller relative om man vil :)...der er lavet 53 uger, men det er jo ikke alle år der har 53 uger. Men vælger uge 53 i et år med 52 uger viser den blot uge 1 det næste uge, selv om den kalder den uge 53....
Der kan du sikkert fylde et eller andet check på hvis du ikke kan acceptere det.
Drop down boksene har jo en lille svaghed da de ikke er dynamiske..eller relative om man vil :)...der er lavet 53 uger, men det er jo ikke alle år der har 53 uger. Men vælger man uge 53 i et år med 52 uger viser den blot uge 1 i næste år, selv om den kalder den uge 53....
Der kan du sikkert fylde et eller andet check på hvis du ikke kan acceptere det.
johan.o ... Det du har et lille problem med ville du ikke have noget problem med hvis du benyttede dato (jeg stopper med at kalde det relativ :D)
Men hvis du ønsker 2 at rette "fejlen" kan du selvfølgelig godt det - ganske "simpelt". Du loader en ny dropdown-menu for "uger" hver gang der vælges et nyt årstal - det gøres vha. javascript.
...nixir...hvad mener du med "Det du har et lille problem med ville du ikke have noget problem med hvis du benyttede dato" ?...de variabler der er i URL'en er de variabler haolan ville have...det kan ganske rigtigt gøres anderledes, men jeg har svært ved at se relevansen :)
...det kan ganske rigtigt laves med javascript...et alternativ kunne måske være...
$oOutput.="<pre>Og hvis du skal søge efter informationer i din database der passer i den viste uge kan du bruge følgende timestamps...</pre>";
$oOutput.="<pre>Start : ".mktime(0, 0, 0, 1, $oDays, $year)." som er ".date("l j. F Y H:i:s", mktime(0, 0, 0, 1, $oDays, $year))."</pre>"; $oOutput.="<pre>Slut : ".mktime(23, 59, 59, 1, $oDays+6, $year)." som er ".date("l j. F Y H:i:s", mktime(23, 59, 59, 1, $oDays+6, $year))."</pre>";
Jaja, kan godt se din pointe med at det vil virke - men hvor prof ser det ud at man kan vælge en uge der ikke eksiterer?
Du har fundet et løsningsforslag, jeg pointerer blot at du kan lave det med javascript så den ikke giver en forkert uge som valgmulighed fra starten af...
Men det er da rigtigt dit vil virke...
Nu spørger jeg fordi jeg er uviden. definerer man uge 1 efter at 4 dage af ugen minimum skal være i det nye år? ( mktime(0, 0, 0, 1, (($week-1)*7)+4, $year)); )
Regner med at fikse noget javascript sammen når jeg kommer til de sidste småjusteringer af siden :)
Takker for dit svar Johan O.. Jeg fik nu min ugevisning til at virke perfekt :) Så mangler jeg bare måneds og årsvisningen, som dog burde være lidt nemmere at få fikset sammen :)
Hmm lige et lille problem jeg lige har opdaget med denne her..
Mine mandage blive ignoreret.. :S
De events jeg som ligger på en mandag bliver ignoreret.. Kan det have noget at gøre med at de ikke har et bestemt klokkeslet? Når jeg opretter dem har de kun en dato.
Det var fordi jeg ikke var klar over hvordan første uge i året er defineret. Men kan godt se din kode overholder ISO...
Men jeg vil stadig våge at påstå, at en mere simpel og huritg kode kunen anvendes med endato, da man sparer udregninger og kan gå stort set direkte til tjek for antal uger.
Men begge dele virker. Jeg er bare tilhænger af at holde koden så lille som mulig - og hurtig!
Men det er nok bare nemmere at overskue med week=xx end en dato i url, det kan jeg også godt se...
Så må man bare vælge side, og haolan havde en klar holdning til at det skulle være efter week=xx, og derfor er det som jeg tidligere nævnte også den løsning han skal vælge. Ellers går han kold i koden første gang han skal ændre noget (hvis det andet ikke er til at gennemskue).
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.