How can I get the 4 Mondays of a month with js?
Asked Answered
C

4

15

I'm building a chart where the x-axis should be the four weeks of a month. I would like to display only the four Mondays of that month.

I already have the currentMonth and the currentYear variables, and I know how to get the first day of the month. All I need is to get the four Mondays of a month in an array. And all of this in the same JavaScript file.

I'm pretty lost within my programming logic, and I've seen plenty of solutions that don't fit my use case.

Right now, I have:

var date = new Date();
var currentYear = date.getFullYear();
var currentMonth = date.getMonth();
var firstDayofMonth = new Date(currentYear, currentMonth, 1);
var firstWeekDay = firstDayofMonth.getDay();

but I would like to have something like this:

var myDates = [
    new Date(firstMonday),
    new Date(secondMonday),
    new Date(thirdMonday),
    new Date(fourthMonday),
];
Camembert answered 28/2, 2012 at 11:36 Comment(4)
A month can have 5 mondays. Like the current month has (february, 2012).Ismaelisman
well, february 2012 does have just 4 mondays, the 6, the 13, the 20 and the 27 (yesterday). it started on a wednesday and end on a wednesday..But i agree, a month could have 5 mondays like april 2012.. and yes, i have to remember that fact when building my codeCamembert
confused by my own calendar, I apologise..Ismaelisman
no problem, the example was confused, but not the aim. thanks, you highlighted a parameter that i have to consider :)Camembert
S
42

The following function will return all Mondays for the current month:

function getMondays() {
    var d = new Date(),
        month = d.getMonth(),
        mondays = [];

    d.setDate(1);

    // Get the first Monday in the month
    while (d.getDay() !== 1) {
        d.setDate(d.getDate() + 1);
    }

    // Get all the other Mondays in the month
    while (d.getMonth() === month) {
        mondays.push(new Date(d.getTime()));
        d.setDate(d.getDate() + 7);
    }

    return mondays;
}
Sevenfold answered 28/2, 2012 at 11:58 Comment(0)
S
4

This would return the fourth last monday of month [m] in year [y]

function lastmonday(y,m) {
 var dat = new Date(y+'/'+m+'/1')
    ,currentmonth = m
    ,firstmonday = false;
  while (currentmonth === m){
    firstmonday = dat.getDay() === 1 || firstmonday;
    dat.setDate(dat.getDate()+(firstmonday ? 7 : 1));
    currentmonth = dat.getMonth()+1;
  }
  dat.setDate(dat.getDate()-7);
  return dat;
}
// usage 
lastmonday(2012,3); //=>Mon Mar 26 2012 00:00:00 GMT+0200
lastmonday(2012,2)  //=>Mon Feb 27 2012 00:00:00 GMT+0100
lastmonday(1997,1)  //=>Mon Jan 27 1997 00:00:00 GMT+0100
lastmonday(2012,4)  //=>Mon Apr 30 2012 00:00:00 GMT+0200

To be more generic, this will deliver the last any weekday of a month:

function lastDayOfMonth(y,m,dy) {
 var  days = {sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6}
     ,dat = new Date(y+'/'+m+'/1')
     ,currentmonth = m
     ,firstday = false;
  while (currentmonth === m){
    firstday = dat.getDay() === days[dy] || firstday;
    dat.setDate(dat.getDate()+(firstday ? 7 : 1));
    currentmonth = dat.getMonth()+1 ;
  }
  dat.setDate(dat.getDate()-7);
  return dat;
 }
// usage 
lastDayOfMonth(2012,2,'tue'); //=>Tue Feb 28 2012 00:00:00 GMT+0100
lastDayOfMonth(1943,5,'fri'); //=>Fri May 28 1943 00:00:00 GMT+0200
Stgermain answered 28/2, 2012 at 12:14 Comment(1)
how can i want to get first also i meant i want to first monday then ?Patten
S
1

For whoever may need, this is a general function to get every monday, tuesday, etc

getDatesOfDayOfWeek (year, month, dayOfWeek) {
      const initialDate = new Date(year, month, 1);
      const datesOfDayOfWeek = [];

      while (initialDate.getDay() !== dayOfWeek) {
        initialDate.setDate(initialDate.getDate() + 1);
      }

      while (initialDate.getMonth() === month) {
        const nextDate = new Date(initialDate.getTime());
        datesOfDayOfWeek.push(nextDate.getDate());
        initialDate.setDate(initialDate.getDate() + 7);
      }

      return datesOfDayOfWeek;
}
Selfregard answered 29/6, 2022 at 7:14 Comment(0)
S
0

I took Jake's code and generalized it to get the next N occurrences of a particular schedule. (e.g. "Get me the next 10 instances of 2nd Mondays and 1st and 3rd Wednesdays.")

  • schedule is an object with keys for day-of-week whose values are an array of the incident within a month that the DoW falls.

    • keys can include numbers from 1-5, and -1 for "last."
    • items in a value array can include numbers from 0-6, where 0 is Sunday.
  • count is optional (defaults to 6) and represents how many items to show.

Samples

  • First and third Mondays would be nextNthMdays({1: [1, 3]})
  • Second Wed and Fri would be nextNthMdays({3: [2], 5: [2]})
  • Last Thursdays would be nextNthMdays({4: [-1]})
function nextNthMdays(schedule, count) {
    var d = new Date(),
        month = 999,
        nthInMonth,
        dates = [];
    if (count == undefined) {
        count = 6;
    }

    // start at the beginning of the month
    d.setDate(1);

    // Iterate until we have enough
    while (dates.length < count) {
        var day = d.getDay();

        // Reset counters each month
        if (d.getMonth() !== month) {
            month = d.getMonth();
            nthInMonth = Object.keys(schedule).reduce(function (obj, x) {
                obj[x] = 0;
                return obj;
            }, {});
        }

        // When you reach an interesting weekday
        if (day in schedule) {
            // Increment its counter
            nthInMonth[day]++;

            // If it's after today
            if (d > new Date()) {
                // and its counter matches
                if (schedule[day].indexOf(nthInMonth[day]) !== -1) {
                    // Add it
                    dates.push(new Date(d.getTime()));
                }
                // or if we want the last one
                else if (schedule[day].indexOf(-1) !== -1) {
                    // verify that 7 days from then is a different month
                    var sevenAway = new Date(d);
                    sevenAway.setDate(sevenAway.getDate() + 7);
                    if (d.getMonth() !== sevenAway.getMonth()) {
                        // Add it
                        dates.push(new Date(d.getTime()));
                    }
                }
            }
        }
        // Move on to the next day
        d.setDate(d.getDate() + 1);
    }
    return dates;
}

Demonstration

Expand the snippet to run some examples.

// `schedule` is an object with keys
//   for day-of-week whose values are
//   an array of the incident within
//   a month that the DoW falls.
//
//   keys can include numbers from
//     1-5, and -1 for "last."
//   items in a value array can include
//     numbers from 0-6, where 0 is
//     Sunday.
//
// `count` is optional (defaults to 6)
//   and represents how many items to
//   show.
//
//   First and third Mondays would be
//     nextNthMdays({1: [1, 3]})
//   Second Wed and Fri would be
//     nextNthMdays({3: [2], 5: [2]})
//   Last Thursdays would be
//     nextNthMdays(4: [-1])
function nextNthMdays(schedule, count) {
    var d = new Date(),
        month = 999,
        nthInMonth,
        dates = [];
    if (count == undefined) {
        count = 6;
    }

    // start at the beginning of the month
    d.setDate(1);

    // Iterate until we have enough
    while (dates.length < count) {
        var day = d.getDay();

        // Reset counters each month
        if (d.getMonth() !== month) {
            month = d.getMonth();
            nthInMonth = Object.keys(schedule).reduce(function (obj, x) {
                obj[x] = 0;
                return obj;
            }, {});
        }

        // When you reach an interesting weekday
        if (day in schedule) {
            // Increment its counter
            nthInMonth[day]++;

            // If it's after today
            if (d > new Date()) {
                // and its counter matches
                if (schedule[day].indexOf(nthInMonth[day]) !== -1) {
                    // Add it
                    dates.push(new Date(d.getTime()));
                }
                // or if we want the last one
                else if (schedule[day].indexOf(-1) !== -1) {
                    // verify that 7 days from then is a different month
                    var sevenAway = new Date(d);
                    sevenAway.setDate(sevenAway.getDate() + 7);
                    if (d.getMonth() !== sevenAway.getMonth()) {
                        // Add it
                        dates.push(new Date(d.getTime()));
                    }
                }
            }
        }
        // Move on to the next day
        d.setDate(d.getDate() + 1);
    }
    return dates;
}

console.log('Next third Wednesdays');
console.log(nextNthMdays({3: [3],}));
console.log('Next first and third Mondays');
console.log(nextNthMdays({1: [1, 3],}, 4));
console.log('Next second Wed/Fridays');
console.log(nextNthMdays({3: [2], 5: [2],}, 3));
console.log('Next "Last Thursdays of the month"');
console.log(nextNthMdays({4: [-1],}, 3));
Shikoku answered 17/8, 2022 at 16:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.