const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
const MSECS_IN_WEEK = MSECS_IN_DAY * 7;


function getCalendarWeekForDate(date) {
    let startOfYear = new Date(date.getFullYear(), 0, 1);
    let sday = startOfYear.getDay();
    let offset = 4 + (7 * Math.floor(sday * (1/5))) - sday;
    let firstThursday = new Date(date.getFullYear(), 0, 1 + offset);
    let weekOfYear = Math.ceil((date.getTime() - firstThursday.getTime()) / MSECS_IN_WEEK);
    return weekOfYear;
}


function getWeekNumber(inDate) {
    // http://en.wikipedia.org/wiki/ISO_week_date#Calculating_the_week_number_of_a_given_date
    let date = new Date(inDate.getFullYear(), inDate.getMonth(), inDate.getDate());
    let jan1st = new Date(date.getFullYear(), 0, 1);
    let diffDate = new Date(date - jan1st);
    let dayNumber = Math.floor(diffDate/MSECS_IN_DAY) + 1;
    let weekNumber = Math.floor((dayNumber - date.getDay() + 10)/7);
    
    if (weekNumber == 53) {
	// check that it isn't actually week 1 of the following year.
	// week 1 is the first week with a Thursday
	let nextYear = new Date(date.getFullYear()+1, 0, 1);
	if (nextYear.getDay() <= 4) {
	    weekNumber = 1;
	}
    }
    if (weekNumber == 0) {
	// find out if it is week 52 or 53 of the preceding year
	let prevYear = new Date(date.getFullYear()-1, 11, 31);
	weekNumber = getWeekNumber(prevYear);
    }
    
    return weekNumber;
}

function test(func) {
    log(func(new Date(2003, 11, 29)) == 1);
    log(func(new Date(2005, 0, 1)) == 53);
    log(func(new Date(2008, 8, 26)) == 39);
    log(func(new Date(2009, 11, 28)) == 53);
    log(func(new Date(2010, 0, 1)) == 53);
    log(func(new Date(2010, 1, 17)) == 7);
}

log("Testing getCalendarWeekForDate");
test(getCalendarWeekForDate);
log("Testing getWeekNumber");
test(getWeekNumber);