Get week of the month

How can i get the week number of month using javascript / jquery?

For ex.:

First Week: 5th July, 2010. / Week Number = First monday

Previous Week: 12th July, 2010. / Week Number = Second monday

Current Date: 19th July, 2010. / Week Number = Third Monday

Next week: 26th July, 2010. / Week Number = Last monday


Solution 1:

This is an old question but the answers that exist are just plain wrong. This is my cross-browser compatible solution:

    Date.prototype.getWeekOfMonth = function(exact) {
        var month = this.getMonth()
            , year = this.getFullYear()
            , firstWeekday = new Date(year, month, 1).getDay()
            , lastDateOfMonth = new Date(year, month + 1, 0).getDate()
            , offsetDate = this.getDate() + firstWeekday - 1
            , index = 1 // start index at 0 or 1, your choice
            , weeksInMonth = index + Math.ceil((lastDateOfMonth + firstWeekday - 7) / 7)
            , week = index + Math.floor(offsetDate / 7)
        ;
        if (exact || week < 2 + index) return week;
        return week === weeksInMonth ? index + 5 : week;
    };
    
    // Simple helper to parse YYYY-MM-DD as local
    function parseISOAsLocal(s){
      var b = s.split(/\D/);
      return new Date(b[0],b[1]-1,b[2]);
    }

    // Tests
    console.log('Date          Exact|expected   not exact|expected');
    [   ['2013-02-01', 1, 1],['2013-02-05', 2, 2],['2013-02-14', 3, 3],
        ['2013-02-23', 4, 4],['2013-02-24', 5, 6],['2013-02-28', 5, 6],
        ['2013-03-01', 1, 1],['2013-03-02', 1, 1],['2013-03-03', 2, 2],
        ['2013-03-15', 3, 3],['2013-03-17', 4, 4],['2013-03-23', 4, 4],
        ['2013-03-24', 5, 5],['2013-03-30', 5, 5],['2013-03-31', 6, 6]
    ].forEach(function(test){
      var d = parseISOAsLocal(test[0])
      console.log(test[0] + '        ' + 
      d.getWeekOfMonth(true) + '|' + test[1] + '                  ' +
      d.getWeekOfMonth() + '|' + test[2]); 
    });

You don't need to put it directly on the prototype if you don't want to. In my implementation, 6 means "Last", not "Sixth". If you want it to always return the actual week of the month, just pass true.

EDIT: Fixed this to handle 5 & 6-week months. My "unit tests", feel free to fork: http://jsfiddle.net/OlsonDev/5mXF6/1/.

Solution 2:

Having struggle with this topic too - thanks to Olson.dev! I've shortened his function a little bit, if somebody is interessted:

// returns week of the month starting with 0
Date.prototype.getWeekOfMonth = function() {
  var firstWeekday = new Date(this.getFullYear(), this.getMonth(), 1).getDay();
  var offsetDate = this.getDate() + firstWeekday - 1;
  return Math.floor(offsetDate / 7);
}

update: if you need a localized version - you have to tweak the firstWeekday variable

// german version - week starts with monday
Date.prototype.getWeekOfMonth = function() {
  var firstWeekday = new Date(this.getFullYear(), this.getMonth(), 1).getDay() - 1;
  if (firstWeekday < 0) firstWeekday = 6;
  var offsetDate = this.getDate() + firstWeekday - 1;
  return Math.floor(offsetDate / 7);
}