Reputation: 6687
I'd like to get the number of calendar rows (weeks) in any month using momentjs
For example:
This would be 5
and this would be 6
Heres what I have to work with:
I have the month, start of month, and end of month as a moment items
const month; // (month moment obj)
const start = moment(month).startOf('month');
const end = moment(month).endOf('month');
Heres what I've tried so far (with no luck)
const weeks = end.diff(start, 'week'); // always gives 4
const weeks = moment.duration(end - start).weeks() + 1; // always gives 5
I really would prefer to use Moment.js for simplicity and accuracy. I've seen some pure JS answers on here but none of them are truly reliable.
Upvotes: 5
Views: 2054
Reputation: 1
Probably this is not the best way to do it, but at least it gives the correct answer.
function getWeeksInMonth(date: Moment | null) {
if (!date) {
return 0;
}
let weeksInMonth = 0;
const firstMonthDate = date.clone().startOf('month');
const lastMonthDate = firstMonthDate.clone().endOf('month');
const currentWeekFirstDate = firstMonthDate.clone().startOf('week');
while (lastMonthDate.isAfter(currentWeekFirstDate)) {
weeksInMonth++;
currentWeekFirstDate.add(1, 'week');
}
return weeksInMonth;
}
Upvotes: -1
Reputation:
You should take in consideration also the offsets.
function weeksOfMonth (input = moment()) {
const startMonth = input.clone().startOf('month');
const startWeek = startMonth.clone().startOf('isoWeek');
const startOffset = startMonth.diff(startWeek, 'days');
const endMonth = input.clone().endOf('month');
const endWeek = endMonth.clone().endOf('isoWeek');
const endOffset = endWeek.diff(endMonth, 'days');
return Math.ceil((endMonth.diff(startMonth, 'days') + startOffset + endOffset) / 7);
}
Upvotes: 0
Reputation: 6302
This is a curious problem. Edited new solution: count the days of the first week (row one), then the next weeks (middle rows), if there are pending days add another row:
Taking into account that week starts on Monday with 'isoWeekDay()'.
As of October 9th 2019:
let now = moment('9/oct/2019');
// First row
let firstWeekDays = 7 - now.startOf('month').isoWeekday() + 1;
let rows = 1
rest = now.daysInMonth() - firstWeekDays;
// Middle rows
let middleRows = Math.floor(rest/7);
rows = rows + middleRows;
rest = rest - (middleRows * 7);
// Last row?
if (rest > 0) {
rows = rows + 1;
}
console.log(rows); // 5
Upvotes: 3