Datum terugrekenen uit het weeknummer
Voor sommige toepassingen is het handig om het weeknummer te berekenen uit een datum. Elders op deze site, in het item "Het weeknummer berekenen", wordt uit de doeken gedaan hoe dat moet.
Op deze bladzijde wordt de omgekeerde weg bewandeld. Er wordt een JavaScript gepresenteerd dat de datum
van maandag (of een andere dag) van een bepaalde week berekent.
Toepassingen voor deze berekening zijn bijvoorbeeld week-jaar formulieren t.b.v. onkostendeclaraties,
urenverantwoording, enz.
De JavaScript code kun je downloaden om zelf te gebruiken.
Hier onder kun je wat gegevens invullen. Als je op de knop Geef Datum klikt, verschijnt de datum van de gekozen week/jaar/dag combinatie in de tekst.
- Er worden twee items besproken:
- Inbouwen in je website
- Algoritme voor de berekening
- De datum wordt berekend door de JavaScript function WeekNrDatum(wk,jr,dg). Deze function staat in de HEAD.
- Op deze bladzijde wordt de informatie die WeekNrDatum() nodig heeft uit een formulier gehaald. In de praktijk is dit niet noodzakelijk het geval, de invoer voor WeekNrDatum() kan ook op een andere manier worden verkregen.
- Het formulier gebruikt de function DoeHetWerk() om WeekNrDatum() aan te roepen en de resultaten te verwerken. De aanpak daarvan hangt echter af van de de context waarin WeekNrDatum() wordt gebruikt.
- Opmerking: Het weeknummer in het formulier wordt berekend door de function WeekNr(). Deze wordt beschreven in de het item "Het weeknummer berekenen". De code staat ook in de downloadfile.
- Opmerking: Voor het weergeven van de dag en de datum zijn de functies ToonDag()
en ToonDatum() gebruikt. Deze staan in de file dagdatum.js en worden besproken in het item:
"Systeem-datum tonen op een web-pagina".
De file dagdatum.js staat in de downloadfile op deze bladzijde.
- Het script gebruikt de weeknummering volgens ISO 8601. Dat betekent dat maandag de eerste dag van de
week is. Zie verder op deze bladzijde.
- De berekening van de datum wordt gedaan door de function WeekNrDatum(wk,jr,dg). Als dit goed verloopt retourneert de function de string 'OK' en staat de berekende datum in de globale datum-variabele WeekNrDatumResult.
- Als de berekening niet goed verloopt (door verkeerde invoer) geeft de function een foutmelding terug.
De variabele WeekNrDatumResult bevat geen zinnige informatie.
- De berekening gaat als volgt:
- Eerst wordt gekeken of de parameter dg aanwezig is. Als dat zo is wordt die gebruikt, anders wordt de defaultwaarde dg = 1 (maandag) gebruikt.
- Vervolgens wordt gecontroleerd of 1 < dg < 7 is. Als dat niet zo is stopt de function met een foutmelding. Maandag is dg = 1, Zondag is dg = 7.
- Vervolgens wordt gekeken of het jaar jr een schrikkeljaar is. Als dat zo is wordt dat onthouden in de variabele schrik. Het aantal dagen van de maand februari wordt op 29 gezet (in de array maanddagen).
- Nu wordt bepaald op welke dag (maandag, dinsdag, ..., enz.) Nieuwjaarsdag van het opgegeven jaar
valt, waarna wordt gekeken of het weeknummer mogelijk is. Er moet gelden: 1 < wk <
53. Als dat niet zo is stopt het script met een foutmelding. Het script stopt ook als wk = 53
is opgegeven voor een jaar dat maar 52 weken heeft.
De condities waar onder een jaar 52 of 53 weken heeft wordt verder op deze bladzijde uitgelegd. - Nu wordt bepaald op welke datum de eerste dag van week 1 valt. De verschuiving ten opzichte van 1 januari de wordt bewaard in de variabele DatumShift.
- Vervolgens wordt een correctie aangebracht voor een andere dag dan maandag en wordt het aantal dagen
sinds Nieuwjaar berekend volgens:
AantalDagen = DatumShift + (wk-1)*7 + dg - 1
- Door in een loop het aantal gepasseerde maanden hier vanaf te trekken wordt de uiteindelijke datum
(dag en maand) bepaald. Het resultaat wordt in de globale datum-variabele WeekNrDatumResult geplaatst.
De function retourneert 'OK'.
- De manier waarop deze function zijn resultaten teruggeeft bepaalt de manier waarop op het resultaat
van WeekNrDatum() moet worden gereageerd:
- Check eerst wat WeekNrDatum() teruggeeft. Als dat 'OK' is, kan er met de WeekNrDatumResult worden doorgewerkt.
- Als WeekNrDatum() iets anders teruggeeft, is er wat fout gegaan. De return-waarde bevat een foutmelding.
- Zie de code van de function DoeHetWerk() voor een voorbeeld.
Als je hier nog wat mee wilt spelen dan kan dat. Klik op de knop hier naast. |
Informatie over de berekening van het weeknummer
ISO 8601 is de Internationale Norm, vastgesteld door de International Organization for Standardization,
die onder andere de nummering van de weken beschrijft.
De Norm stelt dat de week begint op een maandag. Dit is dus de eerste dag van de week. Daardoor is de
zondag de laatste dag van de week, dag nummer 7. Dit wijkt af van het gangbare idee (die in de meeste
maandkalenders en programmeertalen wordt gebruikt (waaronder JavaScript), dat de eerste dag van de week
de zondag is. Men heeft echter gekozen voor de maandag als eerste dag, omdat het tegelijk de eerste werkdag
van de week is. Moderne weekagenda's beginnen hun week ook met de maandag.
Omdat de week 7 dagen heeft, is de eerste week van het jaar de week die 4 (is afgerond de helft van 7) of meer dagen in dat jaar heeft.
Valt 1 januari op een maandag, dan heeft die week 7 dagen in het nieuwe jaar en is het daarom week 1.
Valt 1 januari op een woensdag, dan heeft die week 2 dagen in het oude en 5 in het nieuwe jaar. Ook deze week is week nummer 1.
Valt 1 januari op een zaterdag, dan heeft die week 5 dagen in het oude en 2 in het nieuwe jaar. Deze week behoort dus nog tot het oude jaar. De eerste week begint dan op 3 januari.
Het is eenvoudig om te zien welke week de eerste van het jaar is. Kijk naar de eerste donderdag van het nieuwe jaar, de vierde dag van de week immers en dus op de helft. Deze week is nummer 1.
Bron: Wikipedia, met aanpassingen.
Informatie over het aantal weken in een jaar
Een jaar heeft 52 weken. Af en toe heeft het echter 53 weken. Dat is het geval als het 1 januari op een
donderdag valt. Het jaar daarop begint dan op een vrijdag.
Zoals blijkt uit onderstaand schema begint week 1 dan op 4 januari. Omdat de maandag van week 52 dan echter
op 28 december valt, heeft zo'n jaar 53 weken.
Schrikkeljaren die met een woensdag of een donderdag beginnen hebben om diezelfde reden ook 53 weken.
1 januari valt op: | week 1 begint dan op: | aantal weken: | idem in schrikkeljaar: |
maandag | 1 januari | 52 | 52 |
dinsdag | 31 december | 52 | 52 |
woensdag | 30 december | 52 | 53 |
donderdag | 29 december | 53 | 53 |
vrijdag | 4 januari | 52 | 52 |
zaterdag | 3 januari | 52 | 52 |
zondag | 2 januari | 52 | 52 |
Bron: Wikipedia, met aanpassingen.
Gebruik:
- De code staat gedeeltelijk in de <HEAD> en gedeeltelijk in de <BODY>.
De code ziet er als volgt uit:
(Hulp functions; Zet deze in de <HEAD>).
<script>
//-- Hulp functions. Voor function WeekNr() zie item 188: Het weeknummer berekenen
function WeekNr(vandaag, terug) {
var GecorrigeerdNieuwjaarsdagNr = new Array(6,7,8,9,10,4,5);
var Jaartal = vandaag.getFullYear() - (terug ? 1 : 0);
var Nieuwjaarsdag = new Date(Jaartal,0,1);
var Dagen = Math.floor((vandaag.getTime() - Nieuwjaarsdag.getTime()) / (24 * 60 * 60 * 1000));
var NieuwjaarsdagNr = GecorrigeerdNieuwjaarsdagNr[Nieuwjaarsdag.getDay()];
var nummer = Math.floor((Dagen + NieuwjaarsdagNr) / 7);
if (nummer == 0) nummer = WeekNr(vandaag,true);
return nummer;
}
//-- Voorbereiding Datum terugrekenen uit weeknummer
var week, jaar, dag;
function DoeHetWerk() {
week = document.getElementById('MijnWeek').value;
jaar = document.getElementById('MijnJaar').value;
dag = document.getElementById('MijnDag').value;
var str = WeekNrDatum(week,jaar,dag);
if (str == 'OK')
document.getElementById("Resultaat").innerHTML = "Deze dag valt op " + ToonDatum(WeekNrDatumResult)
else
document.getElementById("Resultaat").innerHTML = str;
}
</script>
(Hoofd rekenfunction; Zet dit in de <HEAD>).
<script>
//-- Datum terugrekenen uit Weeknummer en Jaartal
var WeekNrDatumResult; function WeekNrDatum(wk,jr,dg) {
var argc = WeekNrDatum.arguments.length; // parameter dg is niet verplicht
var wkdg = (argc > 2) ? parseInt(dg) : 1; // default: 1, maandag
if (dg < 1 || dg > 7) return('** WeekNrDatum: Fout: een week heeft 7 dagen.');
var maanddagen = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var schrik = false; // Schrikkeljaar?
if(jr % 4 == 0 && jr % 100 != 0 || (jr % 400 == 0)) {
schrik = true; maanddagen[1] = 29;
}
// Bepaal de dag van 1 januari
Nieuwjaarsdag = new Date(jr,0,1);
NieuwJaarsdagDag = Nieuwjaarsdag.getDay();
// check weeknummer
if (wk < 1 || wk > 53) return('** WeekNrDatum: Fout: Ongeldig weeknummer: '+wk);
// check of week 53 mogelijk is, indien nodig
if (wk == 53) {
if (schrik) {
if (NieuwJaarsdagDag != 4) return('** WeekNrDatum: Fout: Dit jaar heeft geen 53 weken');
} else {
if (NieuwJaarsdagDag != 4 && NieuwJaarsdagDag != 3) return(' WeekNrDatum:** Fout: Dit jaar heeft geen 53 weken');
}
}
// Bepaal verschuiving voor de datum van de maandag van week 1
var DatumShift;
switch (NieuwJaarsdagDag) {
case 0: DatumShift = 2; break; // Zondag, week 1 begint op 2-1
case 1: DatumShift = 1; break; // Maandag, week 1 begint op 1-1
case 2: DatumShift = 0; break; // Dinsdag, week 1 begint op 31-12
case 3: DatumShift = -1; break; // Woensdag, week 1 begint op 30-12
case 4: DatumShift = -2; break; // Donderdag, week 1 begint op 29-12
case 5: DatumShift = 4; break; // Vrijdag, week 1 begint op 4-1
case 6: DatumShift = 3; break; // Zaterdag, week 1 begint op 3-1
}
// Bereken aantal dagen en tel op bij maandag van week 1; verwerk ook andere dag dan maandag
var AantalDagen = DatumShift + (wk-1)*7 + wkdg - 1;
// Reken de datum terug
var maand = 0;
while (AantalDagen > maanddagen[maand]) {
AantalDagen -= maanddagen[maand];
maand++;
}
WeekNrDatumResult = new Date(jr,maand,AantalDagen,0,0,0,0);
return('OK');
}
</script>
(Code van het formulier uit het voorbeeld. Zet dit in de <BODY>, op de plaats waar je het nodig hebt)
<div align="center">
<form action="JavaScript:DoeHetWerk();" method="post" name="Formulier" id="Formulier">
Week: <input type="text" name="MijnWeek" id="MijnWeek" value="1" size="2" maxlength="2">
Jaar: <input type="text" name="MijnJaar" id="MijnJaar" value="1" size="5" maxlength="4">
Dag: <select name="MijnDag" id="MijnDag" size="1" width="30">
<option value="1" selected>Maandag</option>
<option value="2">Dinsdag</option>
<option value="3">Woensdag</option>
<option value="4">Donderdag</option>
<option value="5">Vrijdag</option>
<option value="6">Zaterdag</option>
<option value="7">Zondag</option>
</select><br> <br>
<input type="submit" value="Geef datum" style="font-weight: bold">
<input type="button" value="Overnieuw" onclick="JavaScript:Overnieuw()">
</form>
<script>
var nu = new Date();
function Overnieuw() {
document.getElementById('MijnJaar').value = nu.getFullYear();
document.getElementById('MijnWeek').value = WeekNr(nu);
}
Overnieuw();
</script>
Downloaden:
Druk op de knop:
File: voorb195.zip, 2450 bytes.