-
-
Save markthiessen/3883242 to your computer and use it in GitHub Desktop.
//note: month is 0 based, just like Dates in js | |
function getWeeksInMonth(year, month) { | |
const weeks = [], | |
firstDate = new Date(year, month, 1), | |
lastDate = new Date(year, month + 1, 0), | |
numDays = lastDate.getDate(); | |
let dayOfWeekCounter = firstDate.getDay(); | |
for (let date = 1; date <= numDays; date++) { | |
if (dayOfWeekCounter === 0 || weeks.length === 0) { | |
weeks.push([]); | |
} | |
weeks[weeks.length - 1].push(date); | |
dayOfWeekCounter = (dayOfWeekCounter + 1) % 7; | |
} | |
return weeks | |
.filter((w) => !!w.length) | |
.map((w) => ({ | |
start: w[0], | |
end: w[w.length - 1], | |
dates: w, | |
})); | |
} | |
exports.getWeeksInMonth = getWeeksInMonth; |
const getWeeksInMonth = require("./getWeeksInMonth").getWeeksInMonth; | |
describe("getWeeksInMonth", () => { | |
test("June 2019 (starts on Saturday)", () => { | |
const weeks = getWeeksInMonth(2019, 5); | |
expect(weeks.length).toBe(6); | |
expect(weeks[0].start).toBe(1); | |
expect(weeks[0].end).toBe(1); | |
}); | |
test("Feb 2021 (starts on Monday)", () => { | |
const weeks = getWeeksInMonth(2021, 1); | |
expect(weeks.length).toBe(5); | |
expect(weeks[0].start).toBe(1); | |
expect(weeks[0].end).toBe(6); | |
expect(weeks[4].start).toBe(28); | |
expect(weeks[4].end).toBe(28); | |
}); | |
test("Aug 2021 (starts on Sunday)", () => { | |
const weeks = getWeeksInMonth(2021, 7); | |
expect(weeks.length).toBe(5); | |
expect(weeks[0].start).toBe(1); | |
expect(weeks[0].end).toBe(7); | |
expect(weeks[4].start).toBe(29); | |
expect(weeks[4].end).toBe(31); | |
}); | |
}); |
/**
- It takes a year and a month as arguments, and returns an array of objects, each object containing
- the start and end dates of the week, and an array of all the dates in that week
- @param year - The year of the month you want to get the weeks for.
- @param month - The month you want to get the weeks for.
- @returns An array of objects.
*/
function getWeeksInMonth(year, month) {
const weeks = []
let firstDate = new Date(year, month, 1)
let lastDate = new Date(year, month + 1, 0)
let numDays = lastDate.getDate()
let dayOfWeekCounter = firstDate.getDay()
for (let date = 1; date <= numDays; date++) {
if (dayOfWeekCounter === 0 || weeks.length === 0) {
weeks.push([])
}
weeks[weeks.length - 1].push(date)
dayOfWeekCounter = (dayOfWeekCounter + 1) % 7
}
/* This is to add the last week of the previous month to the first week of the current month. */
if (weeks[0].length < 7) {
const beforeIndex1 = addMonth(year, month - 1, 1)
const indexRefactor = [...beforeIndex1, ...weeks[0]]
weeks[0] = indexRefactor
}
/* This is to add the first week of the next month to the last week of the current month. */
if (weeks[weeks.length - 1].length < 7) {
const afterIndex1 = addMonth(year, month + 1, 0)
const indexRefactor = [...weeks[weeks.length - 1], ...afterIndex1]
weeks[weeks.length - 1] = indexRefactor
}
return weeks
.filter((w) => !!w.length)
.map((w) => ({
start: w[0],
end: w[w.length - 1],
dates: w,
}))
}
/**
- It takes a year, month, and flag, and returns the first or last week of the month, depending on the flag
- @param year - the year of the month you want to get
- @param month - The month you want to get the first or last week of.
- @param flag - 0 for first week, 1 for last week, 2 for all weeks
- @returns An array of arrays.
*/
const addMonth = (year, month, flag) => {
const weeks = [],
firstDate = new Date(year, month, 1),
lastDate = new Date(year, month + 1, 0),
numDays = lastDate.getDate()
let dayOfWeekCounter = firstDate.getDay()
for (let date = 1; date <= numDays; date++) {
if (dayOfWeekCounter === 0 || weeks.length === 0) {
weeks.push([])
}
weeks[weeks.length - 1].push(date)
dayOfWeekCounter = (dayOfWeekCounter + 1) % 7
}
if (flag === 0) {
return weeks[0]
}
if (flag === 1) {
return weeks[weeks.length - 1]
}
return []
}
console.table(getWeeksInMonth(2024, 0))
If you want a function to return a month's week based on business days this shall work:
Results for Oct 2020:
Results for Feb 2020:
Results for March 2020: