Calculating Dutch weeknumbers

Calculating Dutch weeknumbers (or in Google-friendly Dutch: Nederlands weeknummer berekenen) is a bit more complex than you’d expect. Luckily there’s a¬†Wikipedia article¬†describing how to do that. I transformed that algorithm into a bit of Javascript. You’re free to use it, if something’s wrong with it please drop me a note.

/***

Calculate Dutch week numbers
Adapted from Wikipedia algorithm (see http://nl.wikipedia.org/wiki/Weeknummer)
Free for use.

Author: mark AT vantzet DOT com

Syntax: getWeekNumber(Date object)

***/
function getWeekNumber(d) {
// Calculates Dutch weeknumber
// See http://nl.wikipedia.org/wiki/Weeknummer

function getDayDiff(d1, d2) {
// Transform d1 and d2 to milliseconds since epoch, subtract,
// and calculate back to whole days (rounding down)
return Math.floor((d1.valueOf() – d2.valueOf()) / 1000 / 60 / 60 / 24);
}
function createDate(year, month, date) {
// Create a new date w/ time set at 00:00:00.000.
// Use UTC functions to prevent timezone problems.
var d = new Date();
d.setUTCMonth(month – 1);
d.setUTCDate(date);
d.setUTCFullYear(year);
d.setUTCHours(0);
d.setUTCMinutes(0);
d.setUTCSeconds(0);
d.setUTCMilliseconds(0);
return d;
}
function getNEN2772WeekDay(d) {
// In calculations, NEN2772 weekdays are used (mon=1,tue=2,..,sun=7)
var n = d.getUTCDay();
return (n > 0 ? n : 7);
}

var nCurrentYear = d.getUTCFullYear();
var dNormalizedDate = createDate(nCurrentYear, d.getUTCMonth() + 1, d.getUTCDate());
var dJanuary4thCurrentYear = createDate(nCurrentYear, 1, 4);
var dJanuary4thPreviousYear = createDate(nCurrentYear – 1, 1, 4);
var dDecember31stPreviousYear = createDate(nCurrentYear – 1, 12, 31);
var dJanuary4thNextYear = createDate(nCurrentYear + 1, 1, 4);

var UK01 = getDayDiff(dNormalizedDate, dJanuary4thCurrentYear);
var UK02 = Math.floor(UK01 / 7);
var UK03 = getNEN2772WeekDay(dNormalizedDate);
var UK04 = getNEN2772WeekDay(dJanuary4thPreviousYear);
var UK05 = getDayDiff(dDecember31stPreviousYear, dJanuary4thPreviousYear);
var UK06 = Math.floor(UK05 / 7);
var UK07 = getNEN2772WeekDay(dDecember31stPreviousYear);
var UK08 = getNEN2772WeekDay(dJanuary4thCurrentYear);
var UK09 = getNEN2772WeekDay(dJanuary4thNextYear);
if (UK07 < UK08 ) { UK10 = 1; } else if (UK07 < UK04) { UK10 = UK06 + 2; } else { UK10 = UK06 + 1; } if (d.getUTCMonth() == 0 && d.getUTCDate() < 4) { if (UK03 < UK08 ) { UK11 = 1; } else { UK11 = UK10; } } else if (d.getUTCMonth() == 11 && d.getUTCDate() >= 29 && UK03 < UK09) { UK11 = 1; } else if (UK03 < UK08 ) { UK11 = UK02 + 2; } else { UK11 = UK02 + 1; } /* Debug. For 1999/8/11 the following checksum should yield true: s = UK01+','+UK02+','+UK03+','+UK04+','+UK05+','+UK06+','+UK07+','+UK08+','+UK09+','+UK10+','+UK11; alert(s == '219,31,3,7,361,51,4,1,2,53,32' ? 'Checksum passed' : 'Checksum failed'); */ return UK11; } [/sourcecode]

Advertisements