31

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

Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
Prasad
  • 58,881
  • 64
  • 151
  • 199
  • 10
    Is it just me who thinks most answers here are overly complex or completely wrong for the OP? I think `Math.ceil(new Date().getDate() / 7)` pretty much gives the `nth` occurrence of the weekday of given date. Most answers here are talking about week numbers instead of weekday occurrence. For instance, no date can ever be `6th` occurrence of weekday (it may indeed fall in the `6th` week of that month) – Fr0zenFyr Apr 09 '19 at 12:32
  • 1
    This worked well for me. Thanks – Abhijith.M Jul 24 '20 at 07:17
  • 1
    @Fr0zenFyr - Your approach is certainly the cleanest (and bonus: it works!) Thanks – Izzi Aug 26 '20 at 06:35
  • @Fr0zenFyr - your answer is correct. Almost everyone else answered a different question: what is the week number of month for some date? – Valentin Dec 16 '20 at 13:49

17 Answers17

33

This is an old question, here is my cross-browser solution based on:

  1. Weeks start on Sunday
  2. The first week of a month is the one that contains the first of the month

So in March 2013:

  • Fri 1 Mar is the first day of week 1
  • Sun 3 Mar is the start of week 2
  • Sun 31 Mar is the start of week 6 (and is the only day in the that week)
  • Mon 1 Apr is the first day of week 1 in April.

    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],
        ['2013-04-01', 1, 1]
    ].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/.

RobG
  • 142,382
  • 31
  • 172
  • 209
Olson.dev
  • 1,766
  • 2
  • 19
  • 39
  • the script returns wrong week date when the month has 5 weeks – IberoMedia Mar 05 '13 at 11:15
  • So it does; looks like I made one assumption too many. I'll fix this answer tonight. – Olson.dev Mar 05 '13 at 16:32
  • great answer; changing the second return to this seemed to patch the problem above for me: return week === weeksInMonth ? index + (weeksInMonth-1) : week; – renevanderark Jul 17 '13 at 05:45
  • 1
    This doesn't work as expected. Looking at the fiddle, it says that, for instance, 2/24/13 is the 5th Sunday of the month, but actually, it's the 4th Sunday of the month. – CMH Oct 04 '13 at 22:16
  • @CMH While you're correct 2/24/13 is the 4th Sunday of the month, it's the 5th week of the month. The function's name is `getWeekOfMonth()`, not `getInstanceOfDayInMonth()` ... the original question is a little vague so I can see where the confusion may lie. While I'm pretty confident in my function now, I'd have to recommend http://momentjs.com/ in favor of it. – Olson.dev Oct 07 '13 at 19:49
  • @Olson.dev Are you sure momentjs has a function call for this? Care to point out for us? – syclee Oct 28 '13 at 00:52
  • @syclee Out of the box, momentjs doesn't have this function; adding [Twix](http://icambron.github.io/twix.js/) (a useful, officially recognized plugin), you could implement a more readable version of this function. It'd be something like... `var a = moment(); var b = moment().startOf('month'); var weekOfMonth = a.twix(b).count('weeks');` This doesn't handle two cases: providing a special return value for "Last" and when `a.isSame(b)`. – Olson.dev Oct 28 '13 at 21:02
  • 1
    @syclee I created an [issue](https://github.com/moment/moment/issues/1232) on momentjs's GitHub repo if you'd like to track it. – Olson.dev Oct 28 '13 at 21:20
  • Stealing a portion of the algorithm for [calculating the week of the year](http://en.wikipedia.org/wiki/ISO_week_date#Calculating_the_week_number_of_a_given_date) on Wikipedia got me to [`0 | (this.getDate() + 11) / 7`](http://plnkr.co/edit/7cQ1Rap9e7VC5fYiTT1q?p=preview) – RevanProdigalKnight May 22 '15 at 20:34
  • 1
    @Olson.dev May I ask what exact really means ? What was it there in the first place ? – bigopon Mar 30 '17 at 00:24
  • @bigopon Please note the latter part of my answer where I mentioned passing `true`. Essentially `exact` indicates whether you want the last week of the month represented to you as a magic number telling you it's the last week or if you want it to be treated the same as every other week in the month. – Olson.dev Mar 30 '17 at 05:09
  • @Olson.dev Thanks. Is the index in the fn job is to indicate whether it's 0 based or 1 based index ? – bigopon Mar 31 '17 at 03:28
  • @bigopon Yup, you got it. – Olson.dev Mar 31 '17 at 12:27
  • While your approach may be correct (I haven't tested), I believe that the OP wanted the other thing as mentioned in one of the comments above, i.e., instance of weekday in the month. For that, my simple solution would be `Math.ceil(new Date().getDate() / 7);`. Anyway, I won't mind posting an answer to gather downvotes from some confused souls out there, that too on an inactive post where the OP wouldn't bother clearing out the confusion. Cheers for your efforts on this answer. – Fr0zenFyr Apr 09 '19 at 12:40
  • @Olson.dev Is there any other way to get `getInstanceOfDayInMonth()` instead as CMH mentioned. Could you share function for that? – Saroj Shrestha May 19 '19 at 07:28
  • This is not working as expected. for input `['2020-04-23 18:00:25', '2020-04-26 18:00:25']` I'm expecting something like 4 & 5 respectively. Getting 4 & 6 – Rager Apr 06 '20 at 16:07
  • @Rager Re-read my answer. :-) In particular, the bit under the code snippet. – Olson.dev Apr 06 '20 at 16:55
  • Great code, but I think your offsetDate calculation should be: `offsetDate = this.getDate() - firstWeekday + 1 – Homunculus Reticulli Dec 10 '20 at 19:53
  • @HomunculusReticulli I don't think you tested your suggestion; just using it on the "unit test" dates in the answer yields 0 passing tests. – Olson.dev Dec 10 '20 at 21:18
  • @Olson.dev actually, I responded to your comment - looking at **my** code suggestion. I'm just starting out with JS. Care to explain that statement? I don't understand why you would add `firstWeekday` to the current date ? – Homunculus Reticulli Dec 10 '20 at 21:43
  • Getting invalid week number for date: "2021-02-28" – Pradip Bhuvani Feb 24 '21 at 07:20
  • 1
    @PradipBhuvani No, you're not -- 6 is expected. If you want 5, pass `true` to the function. Please re-read my answer; in particular, the bit under the code snippet. – Olson.dev Feb 24 '21 at 14:55
11

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);
}
Lord Midi
  • 754
  • 1
  • 9
  • 25
  • I found this only works with `offsetDate = this.getDate() + firstWeekday - 2`, otherwise it returns the wrong value for Sunday – SystemParadox Sep 18 '19 at 13:53
  • 1
    I think what you need is like a localized variant of the function. I've updated the code with another example - maybe this helps. – Lord Midi Sep 19 '19 at 10:51
  • 1
    Olso.dev version did not work for me in April 2020.. This works brilliantly, thanks. – Rager Apr 06 '20 at 16:10
4

I think this works. It returns the week of the month, starting at 0:

var d = new Date();
var date = d.getDate();
var day = d.getDay();

var weekOfMonth = Math.ceil((date - 1 - day) / 7);
Eric
  • 962
  • 8
  • 12
3

I think you want to use weekOfMonth so it will give 1-4 or 1-5 week of month. I solved the same problem with this:

var dated = new Date();
var weekOfMonth = (0 | dated.getDate() / 7)+1;
Bugs
  • 4,491
  • 9
  • 32
  • 41
3
function getWeekOfMonth(date) {
  const startWeekDayIndex = 1; // 1 MonthDay 0 Sundays
  const firstDate = new Date(date.getFullYear(), date.getMonth(), 1);
  const firstDay = firstDate.getDay();

  let weekNumber = Math.ceil((date.getDate() + firstDay) / 7);
  if (startWeekDayIndex === 1) {
    if (date.getDay() === 0 && date.getDate() > 1) {
      weekNumber -= 1;
    }

    if (firstDate.getDate() === 1 && firstDay === 0 && date.getDate() > 1) {
      weekNumber += 1;
    }
  }
  return weekNumber;
}

I hope this works Tested until 2025

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Mow
  • 51
  • 2
2
week_number = 0 | new Date().getDate() / 7
sigmaxf
  • 7,998
  • 15
  • 65
  • 125
Ishaan Puniani
  • 646
  • 2
  • 10
  • 23
  • 1
    for date 2016-08-07, it gives week number as 1. And for for date 2016-08-08 also, it gives week number as 1? is this correct? – Krishna Shetty Sep 27 '16 at 13:31
2

This is a few years on, but I've needed to use this functionality recently and, for certain dates in years 2016/2020 (such as January 31st), none of the code here works.

It's not the most efficient by any means, but hopefully this helps someone out as it's the only thing I could get working for those years along with every other year.

Date.prototype.getWeekOfMonth = function () {
    var dayOfMonth = this.getDay();
    var month = this.getMonth();
    var year = this.getFullYear();
    var checkDate = new Date(year, month, this.getDate());
    var checkDateTime = checkDate.getTime();
    var currentWeek = 0;

    for (var i = 1; i < 32; i++) {
        var loopDate = new Date(year, month, i);

        if (loopDate.getDay() == dayOfMonth) {
            currentWeek++;
        }

        if (loopDate.getTime() == checkDateTime) {
            return currentWeek;
        }
    }
};
Chris Dixon
  • 9,147
  • 5
  • 36
  • 68
  • Partially working, for instance, 2015-11-30 is in sixth week but your code is showing in fifth week (week start with Monday). – ajreal Oct 28 '15 at 05:48
  • I know it's been 7 months since you posted this but I tested your dates 01/31/2016 and 01/31/2020 with my answer's function and got the expected results (2016 = 6|6, 2015 = 5|6 ... meaning exactly 6th week, also "Last week" (6) for 2016 *and* exactly 5th week, also "Last week" (6) for 2020). – Olson.dev Jan 15 '16 at 10:30
2
import getWeekOfMonth from 'date-fns/getWeekOfMonth'
...
let weekOfMonth = getWeekOfMonth(new Date())

https://date-fns.org/v2.0.0-alpha.9/docs/getWeekOfMonth

貟元奇
  • 21
  • 1
2

None of the previous solutions included the "Last" on the response and I was able to do it by checking the next occurrence of the same day of the week and checking if it's still on this month.

The accepted answer fails in many cases (I tested it with today's date - 2021-05-14 - and it returned "Third Friday" when it's actually the second).

This code below was tested even with April 2017 (a rare case of a month with 6 weeks).

April 2017 - month with 6 weeks

/**
 * Get the week number of the month, from "First" to "Last"
 * @param {Date} date 
 * @returns {string}
 */
 function weekOfTheMonth(date) {
  const day = date.getDate()
  const weekDay = date.getDay()
  let week = Math.ceil(day / 7)
  
  const ordinal = ['First', 'Second', 'Third', 'Fourth', 'Last']
  const weekDays  = ['Sunday','Monday','Tuesday','Wednesday', 'Thursday','Friday','Saturday']
  

  // Check the next day of the week and if it' on the same month, if not, respond with "Last"
  const nextWeekDay = new Date(date.getTime() + (1000 * 60 * 60 * 24 * 7))
  if (nextWeekDay.getMonth() !== date.getMonth()) {
    week = 5
  }
  
  return `${ordinal[week - 1]} ${weekDays[weekDay]}`
}

const days = [
  new Date('2021-05-14'),
  new Date('26 July 2010'),
  new Date('5 July 2010'),
  new Date('12 July 2010'),
  new Date('22 April 2017'),
  new Date('29 April 2017'),
]

for (let i = 0; i < days.length; i += 1) {
  const d = days[i]
  console.log(d, weekOfTheMonth(d))
}
Eduardo Russo
  • 4,121
  • 2
  • 22
  • 38
0

I was just able to figure out a easier code for calculate the number of weeks for a given month of an year ..

y == year for example { 2012 } m == is a value from { 0 - 11 }

function weeks_Of_Month( y, m ) {
    var first = new Date(y, m,1).getDay();      
    var last = 32 - new Date(y, m, 32).getDate(); 

    // logic to calculate number of weeks for the current month
    return Math.ceil( (first + last)/7 );   
}
Prasad
  • 57
  • 5
0

This is nothing natively supported.

You could roll your own function for this, working from the first day of the month

var currentDate = new Date();
var firstDayOfMonth = new Date( currentDate.getFullYear(), currentDate.getMonth(), 1 );

And then getting the weekday of that date:

var firstWeekday = firstDayOfMonth.getDay();

... which will give you a zero-based index, from 0-6, where 0 is Sunday.

David Hedlund
  • 128,221
  • 31
  • 203
  • 222
0
function weekNumberForDate(date){

    var janOne = new Date(date.getFullYear(),0,1);
    var _date = new Date(date.getFullYear(),date.getMonth(),date.getDate());
    var yearDay = ((_date - janOne + 1) / 86400000);//60 * 60 * 24 * 1000
    var day = janOne.getUTCDay();
    if (day<4){yearDay+=day;}
    var week = Math.ceil(yearDay/7);

   return week;
}

Apparently the first week of the year is the week that contains that year's first Thursday.

Without calculating the UTCDay, the returned week was one week shy of what it should have been. Not confident this can't be improved, but seems to work for now.

Johnny Rockex
  • 4,136
  • 3
  • 35
  • 55
0
function getWeekOfMonth(date) {

  var nth = 0; // returning variable.
  var timestamp = date.getTime(); // get UTC timestamp of date.
  var month = date.getMonth(); // get current month.
  var m = month; // save temp value of month.

  while( m == month ) {  // check if m equals our date's month.
    nth++; // increment our week count.
    // update m to reflect previous week (previous to last value of m).
    m = new Date(timestamp - nth * 604800000).getMonth();
  }

  return nth;

}
dzimney
  • 565
  • 1
  • 5
  • 15
0

After reading all the answers I figured out a way that use less CPU than the others and work for every day of every month of every year. Here is my code:

function getWeekInMonth(year, month, day){

    let weekNum = 1; // we start at week 1

    let weekDay = new Date(year, month - 1, 1).getDay(); // we get the weekDay of day 1
    weekDay = weekDay === 0 ? 6 : weekDay-1; // we recalculate the weekDay (Mon:0, Tue:1, Wed:2, Thu:3, Fri:4, Sat:5, Sun:6)

    let monday = 1+(7-weekDay); // we get the first monday of the month

    while(monday <= day) { //we calculate in wich week is our day
        weekNum++;
        monday += 7;
    }

    return weekNum; //we return it
}

I hope this can help.

0

Please try below function.This one is considering week start date as Monday and week end date as Sunday.

getWeekNumber(date) {
    var monthStartDate =new Date(new Date().getFullYear(), new 
         Date().getMonth(), 1);
    monthStartDate = new Date(monthStartDate);
    var day = startdate.getDay();
    date = new Date(date);
    var date = date.getDate();
    return Math.ceil((date+ day-1)/ 7);
}
0

You just need this:

Math.ceil(new Date().getDate() / 7)
blackgreen
  • 34,072
  • 23
  • 111
  • 129
rongding
  • 29
  • 4
-1

function weekAndDay(date) {
    
    var days = ['Sunday','Monday','Tuesday','Wednesday',
                'Thursday','Friday','Saturday'],
        prefixes = ['First', 'Second', 'Third', 'Fourth', 'Fifth'];

    return prefixes[Math.floor(date.getDate() / 7)] + ' ' + days[date.getDay()];

}

console.log( weekAndDay(new Date(2010,7-1, 5)) ); // => "First Monday"
console.log( weekAndDay(new Date(2010,7-1,12)) ); // => "Second Monday"
console.log( weekAndDay(new Date(2010,7-1,19)) ); // => "Third Monday"
console.log( weekAndDay(new Date(2010,7-1,26)) ); // => "Fourth Monday"
console.log( weekAndDay(new Date()) );

Adding the capability to have Last ... may take some more hacking...

Dominique Fortin
  • 2,212
  • 15
  • 20
James
  • 109,676
  • 31
  • 162
  • 175
  • 1
    this is perfect for me. Thanks for the solution. I have replaced fifth as last which is same as the repeat event (Monthly) in google calendar. – Prasad Jul 19 '10 at 11:17
  • 10
    -1, this does not work. Expected: 3, 7, 7, 7, 7. Actual: 6, 7, 7, 7, 4. Code: var c = {'0':0,'1':0,'2':0,'3':0,'4':0}; for (var i = 1; i <= 31; i++) { c[(0 | new Date(2012, 2, i).getDate() / 7).toString()]++; } console.log(c); – Olson.dev Mar 07 '12 at 17:35
  • 3
    this wont work if the month isn't starting with monday – nilsK May 13 '14 at 09:21
  • code is wrong If Date is new Date(2015,8,7); than return "Second Monday" – Ashish Vaghasiya Nov 04 '15 at 09:14
  • @Olson.dev @JayShukla @AshishVaghasiya The month is expressed from 0 to 11 so `new Date(2015,8,7)` is for September 7th of 2015 and not for August. The code works. – Dominique Fortin Nov 08 '18 at 18:48
  • 2
    It doesn't work for many cases using `Math.floor(date.getDate() / 7)`. But works if you replace it by `Math.ceil(date.getDate() / 7 - 1)`. Today, for instance, is the 14, but it's the second Friday of the month, as the Month started on a Saturday. – Eduardo Russo May 14 '21 at 13:25
  • 1
    @EduardoRusso's fix gives the correct result. Should update the solution to prevent further confusion – Alex Wohlbruck Jun 08 '21 at 05:06