Avatar billede baronen20 Nybegynder
12. juni 2003 - 15:55 Der er 14 kommentarer

Find dato

Kan jeg få php til at finde nogle datoer ud fra et ugenummer?

Ex: Jeg vil gerne have datoerne på den første og den sidste dag i uge 35.
Avatar billede nicklasb Nybegynder
12. juni 2003 - 15:59 #1
har jeg næsten lige hjulpet en anden med i et andet spørgsmål.. men her får du lige koden igen:

<?

function startdateofweek($year, $week) {
    $thisyear = mktime(0,0,0,1,1,$year);
    $yearandweek = (( $week - 1 ) * 604800) + $thisyear;
    $dayofweek = ( date('w', $yearandweek) ) - 1;
    $dbdowamow = $dayofweek * 86400;
    $mondayofweek = $yearandweek - $dbdowamow;
    if (date('w',$thisyear) > 4) {
        $dateofweekandyear = date ('d-m-Y', $mondayofweek + 604800);
    } else {
        $dateofweekandyear = date ('d-m-Y', $mondayofweek);
    }
    return $dateofweekandyear;
}

# ==========================================
# Funktionen omdanner et årstal samt et
# ugenummer til datoen, på mandagen i samme
# uge.
#
# Funktionen tager hensyn til problematikken
# omkring hvilken uge den 1/1 falder.
# Reglen går ud på at, hvis den 1/1 er en
# fredag eller derefter, starter uge ét
# først mandagen efter.
# Se evt. mere på :
# http://www.eksperten.dk/spm/361479
#
# ------------------------------------------
# Eksempel:
#
#  -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
#    echo startdateofweek(2003, 4);
#  -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
#
# Vil "omdanne" de to inputs til en dato af
# formatet 2 (dd-mm-yyyy).
# Første input er årstallet, og andet input
# er ugenummeret. (altså uge 4 i år 2003)
# ------------------------------------------
#
# Koden er som den står her, langt fra
# optimeret, men kan bruges som den er :D
# ==========================================
?>
Avatar billede nicklasb Nybegynder
12. juni 2003 - 16:00 #2
for at finde den sidste dato er det jo så bare at ligge 6*24*60*60 til.. :D
Avatar billede nicklasb Nybegynder
12. juni 2003 - 16:08 #3
og en lille omskivning til dit problem (og en lettere måde end at skulle regne det om efterfølgende for at tilføje de 6 dage kunne så se således ud:

<?

function startdateofweek($year, $week) {
    $thisyear = mktime(0,0,0,1,1,$year);
    $yearandweek = (( $week - 1 ) * 604800) + $thisyear;
    $dayofweek = ( date('w', $yearandweek) ) - 1;
    $dbdowamow = $dayofweek * 86400;
    $mondayofweek = $yearandweek - $dbdowamow;
    if (date('w',$thisyear) > 4) {
        $dateofweekandyear = $mondayofweek + 604800;
    } else {
        $dateofweekandyear = $mondayofweek;
    }
    return $dateofweekandyear;
}

// Her starter din php-kode.. Det ovenstående er funktionen, hvis du skulle være i tvivl.. :D
$monday = startdateofweek(date('Y'), 35);
$sunday = $monday + 518400;

echo 'Mandag den ' . date('Y-m-d', $monday) . ' og søndag den ' . date('Y-m-d', $sunday);
?>

Den vil udskrive datoen for mandag og søndag i uge 35 dette år (dette pr fordi koden ændre sig næste år, med de parametre den har fået.. ;)
Avatar billede nicklasb Nybegynder
12. juni 2003 - 16:11 #4
(og en lettere måde end at skulle regne det om efterfølgende for at tilføje de 6 dage_)_ kunne ..

(dette _år_ fordi ..

hvis den skal vise det for år 2003 ALT tid kan du kigge lidt på hvordan det er gjordt i min første kommentar.. Altså med 2003 i stedet ofr (date('Y')

men prøv dig frem.. :D
Avatar billede tipsen Nybegynder
12. juni 2003 - 16:24 #5
nicklasb: Det må du kunne gøres hurtigere?

Hvad er reglen - i DK er uge 1 den uge som indeholder årets første torsdag - ikke?
Avatar billede tipsen Nybegynder
12. juni 2003 - 16:24 #6
"Det må _da_ kunne..."
Avatar billede nicklasb Nybegynder
12. juni 2003 - 16:34 #7
kan SAKTENS gøres hurtigere.. jeg gidder bare ikke sidde og optimere koder for ekspertens brugere.. De kan bruge mine forslag som en ide til hvordan koden kan udformes.. også lidt derfor at koden er penslet så meget ud..

men jo.. efter hvad jeg forstod var det den uge der indeholdte den første torsdag der var uge i.. ( se evt. http://www.eksperten.dk/spm/361479 )

hvis DU gidder optimere er det fint med mig.. men gør det ikke før jeg selv ser det som en udfordring, eller jeg selv skal bruge koden til noget seriøst..
Avatar billede nicklasb Nybegynder
12. juni 2003 - 16:57 #8
men ved nu heller ikke om det er så slemt igen, hvis det endelig er at koden skal kunne rettes, at bruge 4 udregninger og en mktime samt to date-funktioner før man har et brugbart resultat..

hvis det er fordi du mener at jeg har brugt et overdrevet brug af date kan jeg saktens give dig ret.. de kunne også saktens have været siftet ud med nogle almindelige beregninger på timestampne..

og generalt kunne den også undvære et par af udregningerne..
men som du kan se i det spørgsmål jeg har linket til, startede den med en kort og god løsning.. Efter forklaringen af den danske kalender, lavede jeg så hurtig lige et par lappe-løsninger, som jeg dog aligevel godt kan acceptere..

og for en nybegynder, som ikke selv kan lave en så let (misforstå mig ikke) funktioen som den, er det mere en rigligt.. Der ser jeg ingen grund til at lave kringlede formler mm..
Avatar billede nicklasb Nybegynder
12. juni 2003 - 17:20 #9
og dum nok som jeg er, tager jeg jo alt kritik som en udfordring.. så har lavet den lidt kortere (men garanteret også mindre gennemskuelig for en nybegynder.. Så ikke denne kode der skal læres noget af..)

function startdateofweek($year, $week) {
    $thisyear = mktime(0,0,0,1,1,$year);
    $thisyday = date('w',$thisyear);
    if ($thisyday > 4) $thisyear = $thisyear + 604800;
    $date = ( $week * 604800 + $thisyear - 604800 - ( ($thisyday - 1) *  86400) );
    return $date;
}

(2 funktionskald og 1-2 udregninger.. (+ et tjek lige som i den anden))

den SKULLE gerne give timestampet for den første mandag i ugen.. men har ikke lige fået testet det, jeg snart skal smutte.. så prøv den lige selv..

(For at finde søndagen kan du jo evt gøre lige som jeg gjorde i mit sidste eksempel..) (men også her er der sikkert kortere udgaver.. :D)
Avatar billede tipsen Nybegynder
13. juni 2003 - 01:24 #10
Synes det var en sjov lille opgave - så her er også et forslag fra mig:

function weektodates($week, $year=0) {
  if ($year == 0) $year = (int) date('Y');
  //find første torsdag efter 1. januar og læg derefter 7*week dage til og træk 3 dage fra
  $mondaytimestamp = strtotime('first thursday', mktime(12,0,0,1,1,$year)) + (7*$week-3)*86400;
  //generer datotekst for mandag i pågældende uge
  $from = date('l d F Y',$mondaytimestamp);
  //generer datotekst for søndag i pågældende uge
  $to  = date('l d F Y',$mondaytimestamp+6*86400);
  return "uge $week : $from - $to";
}
$uge = 42;
echo weektodates($uge);            //kald uden årstal bruger aktuelt år som standard
echo weektodates($uge, 2002);      //kald med andet årstal

Nogle af udregningerne kan selvfølgelig reduceres - men det sker på bekostning af læsevenligheden, så det har jeg udeladt her! (86400 er antal sekunder på en dag)
Avatar billede nicklasb Nybegynder
13. juni 2003 - 13:02 #11
ok... kunne godt være den skal laves lidt om.. eller er det bare mig der ikke har forstået hvordan variablerne skal være??
har du prøvet det du har skrevet??

har prøvet med $uge = 1;
og har så skrevet en række af echo weektodates($uge, 20xx); med forskellige årstal fra 2000 til 2017..

resultatet er som følger:

uge 1 : Monday 10 January 2000 - Sunday 16 January 2000
uge 1 : Monday 08 January 2001 - Sunday 14 January 2001
uge 1 : Monday 07 January 2002 - Sunday 13 January 2002
uge 1 : Monday 06 January 2003 - Sunday 12 January 2003
uge 1 : Monday 05 January 2004 - Sunday 11 January 2004
uge 1 : Monday 10 January 2005 - Sunday 16 January 2005
uge 1 : Monday 09 January 2006 - Sunday 15 January 2006
uge 1 : Monday 08 January 2007 - Sunday 14 January 2007
uge 1 : Monday 07 January 2008 - Sunday 13 January 2008
uge 1 : Monday 05 January 2009 - Sunday 11 January 2009
uge 1 : Monday 11 January 2010 - Sunday 17 January 2010
uge 1 : Monday 10 January 2011 - Sunday 16 January 2011
uge 1 : Monday 09 January 2012 - Sunday 15 January 2012
uge 1 : Monday 07 January 2013 - Sunday 13 January 2013
uge 1 : Monday 06 January 2014 - Sunday 12 January 2014
uge 1 : Monday 05 January 2015 - Sunday 11 January 2015
uge 1 : Monday 11 January 2016 - Sunday 17 January 2016
uge 1 : Monday 09 January 2017 - Sunday 15 January 2017

Generalt for dem alle, kan det siges at igen af datoerne passer..
ved ikke om du bare mangler at trække en uge fra hver gang.. Men der er i hvert falde en fejl som skal rettes hvis det er den løsning der skal bruges..

og nu er det ikke for at jordere dig.. alt respekt for at du gider tage udfordringen..
men er det hurtigere med dine 5 funktions-kald frem for mine 2 (højrest 4 hvis slutformatet skal skrives rigtigt ud..)
Avatar billede tipsen Nybegynder
13. juni 2003 - 13:23 #12
Fejlen er selvfølgelig, at der er skudt 1 uge for langt frem hele tiden - rettelse:

function TIweektodates($week, $year=0) {
  if ($year == 0) $year = (int) date('Y');
  $mondaytimestamp = strtotime('first thursday', mktime(12,0,0,1,1,$year)) + (7*$week-10)*86400;
  $from = date('l d F Y',$mondaytimestamp);
  $to  = date('l d F Y',$mondaytimestamp+6*86400);
  return "uge $week : $from - $to";
}

Antal af funktionskald kan i min barberes ned til 3 for at få samme funktionalitet som din - det ekstra funktionskald i forhold til dine 2 er til strtotime() som erstatter nogle af dine udregninger og de to ekstra er henholdsvis en ekstra funktionalitet med årstal samt en slutdato, som du også mangler.

Jeg ved faktisk ikke hvordan hastigheden er, men du kan jo lægge din udgave til test som du ønsker den skal se ud (optimer den så meget som muligt, hvis du har lyst) og så kan jeg optimere min og se, hvad resultatet bliver :-)

(Tror primært det der tager tid er udskrivningerne til skærmen!)
Avatar billede nicklasb Nybegynder
13. juni 2003 - 13:33 #13
er lidt lige glad med hvilken der er hurtigts.. men for at pointere det igen; Jeg ser ikke hvad det er der i din er langt bedre end den jeg postede i går.. hvad er det der skulle gøre den så meget bedre??
Avatar billede tipsen Nybegynder
13. juni 2003 - 18:43 #14
nicklasb: Den er ikke nødvendigvis bedre - hvilket jeg heller ikke har påstået på noget tidspunkt - det er bare et alternativ! Mht. antal funktionskald osv. er det ekstra antal jo bare for at give et brugervenligt output - med samme funktionalitet som din kan problemet barberes ned til en enkelt linie:

function TIweektodates2($week, $year) {
  return strtotime('first thursday', mktime(12,0,0,1,1,$year)) + (7*$week-10)*86400;
}

Jeg kan så godt lide ideen med at finde første torsdag i året - trække 3 dage fra for at komme tilbage til mandag og derefter lægge det nødvendige antal uger til resultatet, hvorefter man er færdig - det er intuitivt synes jeg!

Mht. optimering synes jeg det er "sjovt" at prøve alternative løsninger for at se, hvilke elementer i php som er specielt tidskrævende og som man derfor skal være ekstra opmærksom på senere hen!
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester