Since you have decided to redefine the beginning of a week, you made it tougher, but since you asked this question, I was intrigued to figure it out. Here's what I came up with:
http://jsfiddle.net/BtR3u/1/
function getDatesByWeekNumber(year, month, weekNum, firstWeekDay) {
var ret = [];
firstWeekDay = firstWeekDay || 0;
var lastWeekDay = 7 + firstWeekDay;
var tempDate = new Date(year, month, 1);
console.log("tempDate: " + tempDate);
var daysInThisMonth = daysInMonth(year, month);
console.log("daysInThisMonth : " + daysInThisMonth);
console.log("lastWeekDay: " + (7 + firstWeekDay));
// Finds the first day of the week looking for
var curMonth = tempDate.getMonth();
var curYear = tempDate.getFullYear();
var weekCounter = 0;
while (weekCounter < weekNum-1 && (curMonth === month && curYear === year)) {
var dayCounter = 0;
var dayPerWeekCounter = tempDate.getDay();
// No more than 7 days No more than virtual last day Same month/year
while ((dayCounter < 7) && (dayPerWeekCounter < lastWeekDay) && (curMonth === month && curYear === year)) {
tempDate.setDate(tempDate.getDate() + 1);
dayPerWeekCounter++;
dayCounter++;
curMonth = tempDate.getMonth();
curYear = tempDate.getFullYear();
}
curMonth = tempDate.getMonth();
curYear = tempDate.getFullYear();
}
console.log("First day of found week: " + tempDate);
if (tempDate.getMonth() === month && tempDate.getFullYear() === year) {
// Finds each day in week specified that doesn't go out of bounds
var dayCounter = 0;
var dayPerWeekCounter = tempDate.getDay();
var dayPerMonthCounter = tempDate.getDate();
// No more than 7 days No more than virtual last day Not past end of month
while ((dayCounter < 7) && (dayPerWeekCounter < lastWeekDay) && (dayPerMonthCounter <= daysInThisMonth)) {
var cur = tempDate.getDate();
ret.push(cur);
tempDate.setDate(cur + 1);
dayCounter++;
dayPerWeekCounter++;
dayPerMonthCounter++;
}
}
return ret;
}
function copyDate(orig) {
return new Date(orig.getTime());
}
function daysInMonth(year, month) {
return new Date(year, month+1, 0).getDate();
}
var the_dates = getDatesByWeekNumber(2012, 11, 2, 1);
console.log("########FINAL ANSWER: " + JSON.stringify(the_dates));
I'm sure there is a much better way to do what I do, so don't yell at me. My brain is fried enough from trying to figure this out. Sorry if the variable names are weird - there were a lot of i
, j
, and k
, so I thought it would be better not to use them...maybe it would've been. I did my best to test many scenarios, and I couldn't find anything not working, but I'm sure there's something that would go wrong.
A few things to note:
I decided to follow Javascript Date
conventions - months start with 0, days of week start with 0, and days of month start with 1. So if you want December, you pass in 11.
Like I said, you have redefined the beginning of a week, so I made that customizable by using the 4th parameter (start with 0). For example, if Monday is the first day of the week (like it seems to be with you), you would use 1
. It is optional and defaults to 0
if you omit it or pass it a falsey value.
The 3rd parameter is the week number of the month you're looking for (start with 1). For example, if you are looking for the 3rd week, you'd use 3
.
It has "safe" checks to make sure it doesn't returns days outside of the month (in case the week you're looking at is something like "28, 29, 30, 31...1, 2, 3" - it won't grab those last 3. Also, it seems to work for cases at the beginning of the month (like this month) where the first day is in the middle of the week and you want the first week.
So the most items it'll return is 7 (a full, valid week). But it is very possible to return less.