I am working on a calendar widget for a project. For any given date, I need to build a 2D array representing the "Month" that the date falls in, where the rows represent weeks in the month and the cells in those rows are individual days. The weeks must start on Monday, and if the month does not start on a Monday, it must "backfill" in the days from the previous month. Similarly, if the last week in the month isn't "full" because it didn't end on a Sunday, fill the last week with the beginning of the following month.
For example, let's use today, May 26th of 2016. Given an input of new Date(2016, 04, 26)
, I would want an output of an array with 6 elements (the weeks), each element itself an array containing 7 date objects (the days). Because May started on a Sunday, the first date in the first week would actually be April 25th (the previous Monday). Because May ends on a Tuesday, the last date in the last week would be June 5th (the following Sunday).
function getCalendarMatrix(date){
var calendarMatrix = []
var startDay = new Date(date.getFullYear(), date.getMonth(), 1)
var lastDay = new Date(date.getFullYear(), date.getMonth()+1, 0)
// Modify the result of getDay so that we treat Monday = 0 instead of Sunday = 0
var startDow = (startDay.getDay() + 6) % 7;
var endDow = (lastDay.getDay() + 6) % 7;
// If the month didn't start on a Monday, start from the last Monday of the previous month
startDay.setDate(startDay.getDate() - startDow);
// If the month didn't end on a Sunday, end on the following Sunday in the next month
lastDay.setDate(lastDay.getDate() + (6-endDow));
var week = []
while(startDay <= lastDay){
week.push(new Date(startDay));
if (week.length === 7){
calendarMatrix.push(week);
week = []
}
startDay.setDate(startDay.getDate() + 1)
}
return calendarMatrix;
}
My code seems like it's working well, but I'm seeking input on any flaws this might have or how I could go about this in a "better" way.