You can create a date for the first of the month, then move it to the first Thursday. Test it against the passed in date and if it's earlier, get the first Thursday for the following month.
The following assumes that if the passed in date is the first Thursday, that Thursday should be returned. It also assumes that the passed in date has its hours zeroed, otherwise if it's the first Thursday it will return the first in the following month.
It also just sets the date to the first Thursday, so no looping to find the day.
function getFirstThursday(date = new Date()) {
// Create date for first of month
let d = new Date(date.getFullYear(), date.getMonth());
// Set to first Thursday
d.setDate((12 - d.getDay()) % 7);
// If before date, get first Thursday of next month
if (d < date) {
d.setMonth(d.getMonth() + 1, 1);
return getFirstThursday(d);
} else {
return d;
}
}
// Some tests
let f = d => d.toLocaleString('en-gb', {
day:'2-digit',weekday:'short',month:'short'
});
[new Date(2020,8, 1), // 1 Sep -> 3 Sep
new Date(2020,8, 2), // 2 Sep -> 3 Sep
new Date(2020,8, 3), // 3 Sep -> 3 Sep
new Date(2020,8,24), // 24 Sep -> 1 Oct
new Date(2020,9, 1), // 1 Oct -> 1 Oct
new Date(2020,9, 2), // 2 Oct -> 5 Nov
new Date(2020,9,26), // 26 Oct -> 5 Nov
new Date(2020,9,27) // 27 Oct -> 5 Nov
].forEach( d => console.log(
`${f(d)} => ${f(getFirstThursday(d))}`
));
The else block is redundant, the second return could just follow the if but it makes things clearer I think.