1

Which is the best way to get the last monday of may, using javascript? I know I can get the last day of the month, and them subtract the difference of the days to the day I want. But, there is a short, more elegant and efficient way to do it?

Thanks

Jr. Hames
  • 215
  • 2
  • 13
  • possible duplicate of [How to get the 4 monday of a month with js?](http://stackoverflow.com/questions/9481158/how-to-get-the-4-monday-of-a-month-with-js) – sachleen Mar 19 '13 at 18:20
  • 1
    @sachleen Getting the first to fourth day of the month is very easy. The problem is that a month can have four to five weeks. So, a month can have 5 mondays instead of just four. My question is only regarding this fifth monday. – Jr. Hames Mar 19 '13 at 18:24
  • The top answer returns all Mondays in a month. The link is meant as a resource, not a definite solution. :) – sachleen Mar 19 '13 at 18:25
  • @sachleen I already know that method, but, is there a better solution? An elegant way? – Jr. Hames Mar 19 '13 at 18:28
  • Actually, it's not a dupe of that other question, It's specific to last day, not ordinal. Specifically, reflects the calculation of United States Memorial Day which is the Last Monday in May. – ssaltman Mar 11 '15 at 16:07
  • `LDOM.date() - (L_DOW - T_DOW) % 7` where LDOM : Last Day of the Month, L_DOW: Last-day-of-month weekday number, T_DOW: Target-day-of-month weekday number. – James VB Feb 09 '22 at 19:10

5 Answers5

1
function getLastMonday(month, year) {
  var d = new Date();
  if (year) { d.setFullYear(year); }
  d.setDate(1); // Roll to the first day of ...
  d.setMonth(month || d.getMonth() + 1); // ... the next month.
  do { // Roll the days backwards until Monday.
    d.setDate(d.getDate() - 1);
  } while (d.getDay() !== 1);
  return d;
}

getLastMonday();        // => Mon Mar 25 2013 12:44:39 GMT-0600 (MDT)
getLastMonday(5);       // => Mon May 27 2013 12:41:52 GMT-0600 (MDT)
getLastMonday(1, 2000); // => Mon Jan 31 2000 12:43:15 GMT-0700 (MST)
maerics
  • 151,642
  • 46
  • 269
  • 291
0

So, I just realize the problem with the other answers is that my question is wrong. What I wanted in the first place, was to check if a given day is the last monday of may (or any other month). Not how to get the last monday of may. Sorry about that.

The best answer to my own question I believe is this one:

function lastMondayOfMay() {
    var d = new Date(2013, 5, 0); //last day of desired month
    return d.getDate() - (d.getDay() - 1);//1 here represents monday
}

For other months, just create date pointing to the last day of the month you want.

Thanks for everyone effort trying to answer this one. But my questions still remains: Which is the best way to know if a given date is the last monday of the month. Using my solution and them comparing the dates is what I'm currently doing. Is there a more direct way of doing it?

I believe this will answer my second question as well:

function isLastMonday(date) {//date format: 'DD/MM/YYYY'
    var d = new Date(date);
    return d.getDay() === 1 && (d.getDate() + 7) > 30; //1 here represents monday
}

isLastMonday('05/27/2013');//true
isLastMonday('05/26/2013');//false
isLastMonday('02/25/2013');//true
isLastMonday('03/24/2013');//false

I'm actually testing with a much larger number of dates and they appear to be fine. Can anyone come with a scenario where my code will fail?

Ok, I will answer this third question as well. The only month this could happen is february. This because to fail my test, the last monday should happen before the 24rd. Since I'm only worried about may (I'm using it to calculate the Memorial Day holiday), I believe my solution will do.

Jr. Hames
  • 215
  • 2
  • 13
0

Posting my solution. I found the other solution had some problems if the last day was Sunday (it returned 32 as the date of the last monday - see Sunday, May 31, 2015.

        function lastMondayOfMay(year, month) {
            var d = new Date(year, month, 0); //last day of desired month
            if (d.getDay() == 0) {
                //deals with sunday - subtracts 6 instead of adding 1
                return d.getDate() - 6;  
                } else {
                return d.getDate() - (d.getDay() - 1);
                }
            return d.getDate() - (d.getDay() - 1);//1 here represents monday
        }
ssaltman
  • 3,623
  • 1
  • 18
  • 21
0

Using javascript without momentjs.

/**
 * @param {number} month - From 0 to 11.
 * @param {number} year
 */
function lastMondayOfMonth(month, year) {
    var WEEK_DAYS = 7;
    var DAY_OF_WEEK = 1; // 1 for monday
    var day;
    var lastDateOfMonth = new Date(year, (month + 1), 0);
    var lastDay = lastDateOfMonth.getDate();
    var lastWeekDay = lastDateOfMonth.getDay();

    if (lastWeekDay === DAY_OF_WEEK) {
        day = lastDay;
    } else if (lastWeekDay < DAY_OF_WEEK) {
        day = lastDay - (WEEK_DAYS - DAY_OF_WEEK);
    } else {
        day = lastDay - (lastWeekDay) + DAY_OF_WEEK;
    }

    return day;
}
-1

I don't know any shorter or more efficient way than this (but then, I'm no JavaScript guru):

var d = new Date( 2013, 5, 0 );
while( d.getDay() != 1 )
{
    d.setDate( d.getDate() - 1 ); 
}
console.log( d.toString() );

(Partially inspired by this answer, that sachleen mentioned in the comments)

But that is basically what you proposed yourself already, in your question.

Community
  • 1
  • 1
Decent Dabbler
  • 22,532
  • 8
  • 74
  • 106
  • I can replace your code with this: ```var d = new Date(2013, 5, 31); console.log(d.getDate() - (d.getDay() - 1));``` – Jr. Hames Mar 19 '13 at 18:41
  • 1
    @Jr.Hames Well, there you go (although I assume you meant `new Date(2013, 4, 31)`). I don't know how much more efficient you expect it to become. If you are searching for PHP's [`strtotime()`](http://www.php.net/manual/en/function.strtotime.php) type of functionality, as far as I know, JavaScript does not support this kind of functionality. PS.: I used `new Date( 2013, 5, 0 )` to signify a way to determine the last day of a month (in this case May) dynamically. – Decent Dabbler Mar 19 '13 at 19:02
  • if the last day of the month is sunday (0), this fails, right? At least it failed for me when May 31 was a Sunday. So I used if (d.getDay() == 0) { return d.getDate() - 6; } else { return d.getDate() - (d.getDay() - 1); } – ssaltman Mar 11 '15 at 16:01