get the number of weeks (rows) in a month from moment.js

Viewed 1299

I'd like to get the number of calendar rows (weeks) in any month using momentjs

For example:

This would be 5

enter image description here

and this would be 6

enter image description here

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.

2 Answers

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

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);
}

Related