You can get the last day of the month then subtract the required number of days based on the difference between the end of month day and required day, e.g.
/* Return last instance of week day for given year and month
* @param {number|string} year: 4 digit year
* @param {number|string} month: calendar month number (1=Jan)
* @param {string} day: English week day name, e.g. Sunday,
* Sun, su, case insensitive
* @returns {Date} date for last instance of day for given
* year and month
*/
function getLastDayOfMonth(year, month, day) {
// Convert day name to index
let i = ['su','mo','tu','we','th','fr','sa'].indexOf(day.toLowerCase().slice(0,2));
// Get end of month and eom day index
let eom = new Date(year, month, 0);
let eomDay = eom.getDay();
// Subtract required number of days
eom.setDate(eom.getDate() - eomDay + i - (i > eomDay? 7 : 0));
return eom;
}
// Examples - last weekdays for Feb 2022
['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'].forEach(day =>
console.log(day.slice(0,3) + ': ' + getLastDayOfMonth('2022', '02', day).toLocaleDateString('en-GB',{
year:'numeric',
month:'short',
day:'numeric',
weekday:'short'
})
));
In the above:
new Date(year, month, 0)
leverages the fact that the month is calendar month whereas the date constructor months are 0 indexed, so the above sets the date to the zeroth day of March, which resolves to the last day in February.
The part:
eom.getDate() - eomDay + i - (i > eomDay? 7 : 0)
subtracts the eomDay index to get to the prior Sunday, then i adds days to get the required day. However, if that goes beyond the end of the month (i.e. i is greater than eomDay so adds more days that eomDay subtracts), it subtracts 7 days.