[PHP] Weeknummer verkrijgen aan de hand van maand en jaar

Pagina: 1
Acties:

Onderwerpen


  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
De onderstaande functie heb ik geprogrammeerd om het weeknummer te verkrijgen aan de hand van een maand en jaar:


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getWeekNumbers($maand, $jaar){
    // Aantal dagen in de maand tellen - voor de for loop
    $aantal = date("t", mktime(0, 0, 0, $maand, 1, $jaar));
    
    for ($i=1; $i<=$aantal; $i++){
        if (date('l',mktime(0,0,0,$maand,$i,$jaar)) == 'Thursday'){
            $weken[] = date('W',mktime(0,0,0,$maand,$i,$jaar));
        }
    } 
    // Retourneer array met weken
    return $weken;
}

// Voorbeeld
echo '<pre>';
print_r(getWeekNumbers(3,2009));



Bovenstaande werkt fantastisch! >:) maar nu mijn vraag: Is het safe aan de hand van de donderdag in die week er vanuit te gaan dat het weeknummer van die dag de juiste is? (Ik heb niet getest of het over 2 jaar of i.c.m. schrikkeljaar ook werkt)

  • Noork
  • Registratie: Juni 2001
  • Niet online
Waarom zou dat niet veilig zijn? Donderdag is een dag midden in een week....

  • Flipke84
  • Registratie: Juli 2008
  • Laatst online: 09-11-2024
Waarom maak je niet gebruik van de functie date()

PHP:
1
$week = date("W", time());

[ Voor 34% gewijzigd door Flipke84 op 12-02-2009 11:23 ]


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dus als aan het einde van de maand enkel de dagen tot woensdag vallen, komt dat weeknummer niet in die maand voor?

{signature}


  • MueR
  • Registratie: Januari 2004
  • Laatst online: 01:55

MueR

Admin Tweakers Discord

is niet lief

kvdd schreef op donderdag 12 februari 2009 @ 11:17:
PHP:
1
if (date('l',mktime(0,0,0,$maand,$i,$jaar)) == 'Thursday')
Waarom niet gewoon vergelijken met date('N'), wat een numerieke representatie geeft van de weekdag ?

Overigens is een weeknummer altijd voor de hele week hetzelfde. Op maandag is deze niet anders dan op donderdag of zondag.

Anyone who gets in between me and my morning coffee should be insecure.


  • Kettrick
  • Registratie: Augustus 2000
  • Laatst online: 13:45

Kettrick

Rantmeister!

MueR schreef op donderdag 12 februari 2009 @ 11:27:
[...]

Waarom niet gewoon vergelijken met date('N'), wat een numerieke representatie geeft van de weekdag ?
Al was het alleen maar omdat dit script stuk gaat zodra je je locale veranderd :X

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Zitten er niet praktisch altijd 5 weeknummers in een maand?

PHP:
1
2
3
4
5
6
7
8
9
10
function getWeekNumbers($maand, $jaar)
{ 
 $d = mktime(0, 0, 0, $maand, 1, $jaar);
 $w = date("W", $d);
 $a = date("t", $d) == 28 ? 4 : 5;
 $r = array();
 for($x = 0; $x < $a; $x++)
   array_push($r, $w+$x);
 return $r;
}


* niet getest overigens

[ Voor 21% gewijzigd door Guillome op 12-02-2009 11:38 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
Guillome schreef op donderdag 12 februari 2009 @ 11:36:
Zitten er niet altijd 5 weeknummers in een maand?
Nope, juni 2008 betrof weken 22, 23, 24, 25, 26 en 27.

En de code van de TS gaat hierop fout omdat de weken 22 en 27 in juni geen donderdag bevatten.

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Ok take 2 :)

PHP:
1
2
3
4
5
6
7
8
9
10
11
function getWeekNumbers($maand, $jaar)
{ 
 $d1 = mktime(0, 0, 0, $maand, 1, $jaar);
 $d2 = mktime(0, 0, 0, $maand, date("t", $d1), $jaar);
 $w = date("W", $d1);
 $a = date("W", $d2) - date("W", $d1);
 $r = array();
 for($x = 0; $x < $a; $x++)
   array_push($r, $w+$x);
 return $r;
}

[ Voor 12% gewijzigd door Guillome op 12-02-2009 11:42 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • MueR
  • Registratie: Januari 2004
  • Laatst online: 01:55

MueR

Admin Tweakers Discord

is niet lief

Je wil gewoon het weeknummer van de eerste dag en de laatste dag van de maand hebben, vervolgens zijn alle tussenliggende nummers automagisch ook binnen die maand.

Anyone who gets in between me and my morning coffee should be insecure.


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Precies :) Dat is net wat ik gedaan heb :D

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
Guillome schreef op donderdag 12 februari 2009 @ 11:43:
Precies :) Dat is net wat ik gedaan heb :D
Het kan nog sneller, mktime() doet leuke dingen met 0e dag enzo:

PHP:
1
2
3
4
5
6
function getWeekNumbers($maand, $jaar){
    $firstWeekNo = date('W',mktime(0,0,0,$maand,1,$jaar));
    $lastWeekNo = date('W',mktime(0,0,0,$maand+1,0,$jaar));

    return range($firstWeekNo, $lastWeekNo);
}

  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
Voutloos schreef op donderdag 12 februari 2009 @ 11:21:
Dus als aan het einde van de maand enkel de dagen tot woensdag vallen, komt dat weeknummer niet in die maand voor?
Dat is inderdaad wat ik denk. Voor zover ik kan zien is dit ook zo.
RoeLz schreef op donderdag 12 februari 2009 @ 11:31:
[...]


Al was het alleen maar omdat dit script stuk gaat zodra je je locale veranderd :X
Dat is inderdaad de reden, het programma draait wel op de machine die ik beheer, maar uitsluiten is beter.
Guillome schreef op donderdag 12 februari 2009 @ 11:36:
Zitten er niet altijd 5 weeknummers in een maand?

...
Nee, kijk bijvoorbeeld naar deze maand, 4 weeknummers. :)

Is het een safe stukkie code programmeurs?

  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
kvdd schreef op donderdag 12 februari 2009 @ 11:46:
Is het een safe stukkie code programmeurs?
Nee, want jouw code kan niet omgaan met juni 2008, augustus 2008, september 2008, etc.

Trouwens, als je twijfelt over je code kun je het beste een testcase schrijven. De simpelste methode daarvoor is gewoon van een jaar of meer de verwachte output vergelijken met de output van jouw functie.

[ Voor 30% gewijzigd door sub0kelvin op 12-02-2009 11:52 ]


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

sub0kelvin schreef op donderdag 12 februari 2009 @ 11:46:
[...]

Het kan nog sneller, mktime() doet leuke dingen met 0e dag enzo:

PHP:
1
2
3
4
5
6
function getWeekNumbers($maand, $jaar){
    $firstWeekNo = date('W',mktime(0,0,0,$maand,1,$jaar));
    $lastWeekNo = date('W',mktime(0,0,0,$maand+1,0,$jaar));

    return range($firstWeekNo, $lastWeekNo);
}
Jep netsies :) Dit lijkt er op

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
sub0kelvin schreef op donderdag 12 februari 2009 @ 11:46:
[...]

Het kan nog sneller, mktime() doet leuke dingen met 0e dag enzo:

PHP:
1
2
3
4
5
6
function getWeekNumbers($maand, $jaar){
    $firstWeekNo = date('W',mktime(0,0,0,$maand,1,$jaar));
    $lastWeekNo = date('W',mktime(0,0,0,$maand+1,0,$jaar));

    return range($firstWeekNo, $lastWeekNo);
}
Even je code getest, en precies waar het mij op fout liep bij het programmeren van deze functie, loopt het ook bij jou fout. Probeer het volgende:

PHP:
1
2
print_r(getWeeknumbers(1,2009));
print_r(getWeeknumbers(2,2009));


Zie je? week 5 paktie vrolijk mee voor februari, en dat klopt niet dus.

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

De fout ligt misschien dat de week niet altijd bij zondag begint. Het ene pakket/omgeving/land/systeem werkt vanaf zondag, en sommige vanaf maandag

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
Tja, ik houd de standaard aan van de NEN 2772: weken beginnen op een maandag.

  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
@Guillome, jouw code maakt ook die fout, dat is juist het lastige van de functie :)
En de code van de TS gaat hierop fout omdat de weken 22 en 27 in juni geen donderdag bevatten.
Brr.. bijna mn functie geimplementeerd. Ik zoek momenteel hard verder hoe ik het dan kan ondervangen, op de donderdag van de week afgaan is niet de juiste manier blijkbaar.

[ Voor 15% gewijzigd door kvdd op 12-02-2009 12:16 . Reden: Verkeerde quote ]


  • Flipke84
  • Registratie: Juli 2008
  • Laatst online: 09-11-2024
Dit klopt wel want 1 februari 2009 is een zondag in week 5 en de functie date('W') als volgt:
ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0)

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

W ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0)
De ISO-8601 week nummering dus, en niet de Gregoriaanse zoals we die in Nederland gebruiken...

edit: wel de definitie zoals wij hem meestal gebruiken :)

[ Voor 12% gewijzigd door crisp op 12-02-2009 12:04 ]

Intentionally left blank


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Dat zeg ik :) En kvdd, mijnes doet hetzelfde omdat de functionaliteit hetzelfde is als de functie van subkelvin. Alleen die van hem is korter endus netter genoteerd :)
Maar wat je zou kunnen doen is dan toch

PHP:
1
2
3
4
5
6
function getWeekNumbers($maand, $jaar){
    $firstWeekNo = date('W',mktime(0,0,0,$maand,0,$jaar));
    $lastWeekNo = date('W',mktime(0,0,0,$maand+1,-1,$jaar));

    return range($firstWeekNo, $lastWeekNo);
}


.... of niet?

[ Voor 46% gewijzigd door Guillome op 12-02-2009 11:59 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
offtopic:
@Guillome: Nu we het toch over weeknummers hebben: je javascript kalendertje doet het fout. http://www.guillome.nl/we...TML/kalender/kalender.php Hij begint bij week 0 ipv 1.

  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
Guillome schreef op donderdag 12 februari 2009 @ 11:56:
Dat zeg ik :) En kvdd, mijnes doet hetzelfde omdat de functionaliteit hetzelfde is als de functie van subkelvin. Alleen die van hem is korter endus netter genoteerd :)
Maar wat je zou kunnen doen is dan toch

PHP:
1
2
3
4
5
6
function getWeekNumbers($maand, $jaar){
    $firstWeekNo = date('W',mktime(0,0,0,$maand,0,$jaar));
    $lastWeekNo = date('W',mktime(0,0,0,$maand+1,-1,$jaar));

    return range($firstWeekNo, $lastWeekNo);
}


.... of niet?
Toch niet, want ik krijg voor maand 1 en 2 van 2009 de volgende output:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Array // Januari
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array // Februari
(
    [0] => 5 // <-- fout
    [1] => 6
    [2] => 7
    [3] => 8
    [4] => 9
)



De laatste array zou moeten zijn:

code:
1
2
3
4
5
6
7
Array // Februari
(
    [0] => 6
    [1] => 7
    [2] => 8
    [3] => 9
)[/

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

sub0kelvin schreef op donderdag 12 februari 2009 @ 12:14:
offtopic:
@Guillome: Nu we het toch over weeknummers hebben: je javascript kalendertje doet het fout. http://www.guillome.nl/we...TML/kalender/kalender.php Hij begint bij week 0 ipv 1.
Ding is in 2001 gemaakt ofzo :P

@Kvdd: en +1 ipv -1 dan?

[ Voor 3% gewijzigd door Guillome op 12-02-2009 12:24 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
Dan hetzelfde resultaat, heeft te maken met de eerste dag van de week. Zijn er geen voorwaardes waaraan gecheckt kan worden bij welke week de datum hoort?

  • Ventrigo
  • Registratie: Juli 2004
  • Niet online

Ventrigo

Het is zeker mijn tube !

offtopic:
Ben dan wel geen programmeur, maar weet wel hoe ik google moet gebruiken ;) . Als ik op "php calendar" zoek in google krijg ik genoeg hits hoe het zou kunnen werken. Al naar gekeken? Link waar het over gaat : http://www.google.nl/sear...week+calendar+php&spell=1 .

Self reflection is the school of wisdom


  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
Ja, daar zijn voorwaarden aan:
- eerste dag van de week is maandag
- eerste week is die waarin de eerste donderdag van dat jaar is
- andere weken kun je gewoon doortellen op basis van die twee premissen

Zie Wikipedia: Weeknummer

Als je zondagen als eerste dag van de week wilt gebruiken kun je volgens mij
PHP:
1
2
3
4
5
6
function getWeekNumbers($maand, $jaar){
    $firstWeekNo = date('W',mktime(0,0,0,$maand,1+1,$jaar));
    $lastWeekNo = date('W',mktime(0,0,0,$maand+1,1,$jaar));

    return range($firstWeekNo, $lastWeekNo);
}

gebruiken.
Alle dagen zijn dan 1tje opgeschoven. Dan krijg je wel problemen aan het einde van het jaar, want $lastWeekNo zal in december kijken naar januari.

[ Voor 45% gewijzigd door sub0kelvin op 12-02-2009 12:37 ]


  • antonboonstra
  • Registratie: Augustus 2002
  • Laatst online: 12:21

antonboonstra

8815Wp | WP | Tesla | Zero

kvdd schreef op donderdag 12 februari 2009 @ 12:19:
[...]

Toch niet, want ik krijg voor maand 1 en 2 van 2009 de volgende output:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Array // Januari
(
    \[0] => 1
    \[1] => 2
    \[2] => 3
    \[3] => 4
    \[4] => 5
)
Array // Februari
(
    \[0] => 5 // <-- fout
    \[1] => 6
    \[2] => 7
    \[3] => 8
    \[4] => 9
)



De laatste array zou moeten zijn:

code:
1
2
3
4
5
6
7
Array // Februari
(
    \[0] => 6
    \[1] => 7
    \[2] => 8
    \[3] => 9
)[/
toon volledige bericht
1 februari is de zondag van week 5, dus het klopt wel (volgens de ISO standaard)

📸Canon EOS 5D IV 🚁DJI Mavic Pro 🏍️Zero SR ⚡Tesla M3 LR 🌡️Daikin US 3.5kW ☀️8815Wp 🔋Marstek Venus-E 5,12 kWh Tweakers PVOutput lijst


  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
antonboonstra schreef op donderdag 12 februari 2009 @ 12:33:
[...]
1 februari is de zondag van week 5, dus het klopt wel (volgens de ISO standaard)
Ja, dat is al meerdere keren aangegeven, maar hij wil de ISO en NEN standaarden niet gebruiken, blijkbaar.

  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
sub0kelvin schreef op donderdag 12 februari 2009 @ 12:35:
[...]

Ja, dat is al meerdere keren aangegeven, maar hij wil de ISO en NEN standaarden niet gebruiken, blijkbaar.
Graag, maar ik zoek hoe ik het kan toepassen ;)

Edit: Volgens mij is je laatste code submit de oplossing. Ik ga dit eerst uitgebreid testen, en post hier de bevindingen.

Edit2: Helaas gaat het alsnog fout (er mogen geen dubbele weken voorkomen):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Array
(
    [0] => 10
    [1] => 11
    [2] => 12
    [3] => 13
    [4] => 14
)
Array
(
    [0] => 14 // <-- fout
    [1] => 15
    [2] => 16
    [3] => 17
    [4] => 18
)


@sub0kelvin: Ik ga de functie wijzigen, het doortellen vanaf week 1 van het jaar is de oplossing denk ik. (Al wil ik graag vanuit een maand en een jaar rekenen)

[ Voor 54% gewijzigd door kvdd op 12-02-2009 13:05 ]


  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
Waarom mogen er geen dubbele weken in voorkomen, kun je dat uitleggen?

Want het eind van de maand is er bijna altijd in het midden van een week. De volgende maand begint dan dus in dezelfde week als de oude maand eindigde. Dat is het probleem met weken van 7 dagen en maanden van 28-31 dagen en jaren van 365/366 dagen, dat verspringt steeds.

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Ja misschien ook handig als je uitlegt waar het voor is? Want wat je nu wilt lijkt heel onlogisch in ieder geval. Het heeft dan niets meer met kalender ofzo te maken.
Anders moet je kijken vanaf de eerste maandag in de maand
PHP:
1
2
3
$d = mktime(0, 0, 0, $maand, 1, $jaar);
$dow = date("N", $d); // 1 voor maandag, 3 voor woensdag, 7 voor zondag
$eerste_week = date("W", mktime(0, 0, 0, $maand, 8-$dow, $jaar);

[ Voor 4% gewijzigd door Guillome op 12-02-2009 13:54 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • kvdd
  • Registratie: Oktober 2004
  • Laatst online: 30-01 09:37
Ik maak geen kalender maar een overzicht, als volgt:
(1)Eerst een rij weeknummers, met (2)daaronder de bijbehorende datums, alleen werkdagen.

@Guillome: een kalender laat het weeknummer ook maar éénmalig zien hoor ;)

[ Voor 21% gewijzigd door kvdd op 12-02-2009 14:33 . Reden: Typo's ]


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Echt niet, dubbelklik maar eens op je klokje rechtsonderin

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router

Pagina: 1