Gaelle
Gaelle

Reputation: 614

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

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),
];

Upvotes: 15

Views: 26053

Answers (4)

Michael come lately
Michael come lately

Reputation: 9333

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

Upvotes: 0

Jairo Erazo
Jairo Erazo

Reputation: 174

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

Upvotes: 1

KooiInc
KooiInc

Reputation: 122906

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

Upvotes: 4

jabclab
jabclab

Reputation: 15042

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

Upvotes: 42

Related Questions