marielle
marielle

Reputation: 438

Find first monday date of month

I have a date (usually the first day of a month but not necessary, it could be any date) and I want a new date corresponding to the first Monday of that month.

example:

findFirstMonday('1 jul 2021') -> 7 jul 2021
findFirstMonday('1 aug 2021') -> 2 aug 2021
findFirstMonday('13 aug 2021') -> 2 aug 2021

Here is my code that doesn't work:

const selectedDate = new Date();

const daysInSelectedDate = daysInMonth(selectedDate);
const lastDayPreviousMonth = addDays(selectedDate, daysInSelectedDate - selectedDate.getDate() + 1);
const firstDayPreviousMonth = removeDays(
  lastDayPreviousMonth,
  daysInMonth(lastDayPreviousMonth),
);
console.log('firstDayPreviousMonth: ', firstDayPreviousMonth);
let firstMonday = firstDayPreviousMonth;
while (firstDayPreviousMonth.getDay() !== 1) {
  console.log('firstMonday: ', firstMonday, firstMonday.getDay());
  firstMonday.setDate(firstMonday.getDate() + 1);
}
console.log('firstMonday: ', firstMonday, firstMonday.getDay());

function addDays(date, days) {
  const result = new Date(date)
  result.setDate(result.getDate() + days)
  return result
}

function removeDays(date, days) {
  const result = new Date(date)
  result.setDate(result.getDate() - days)
  return result
}

function daysInMonth(date) {
  return new Date(date.getFullYear(), date.getMonth(), 0).getDate()
}

What am I wrong? Thanks a lot

Upvotes: 1

Views: 1821

Answers (2)

Lucas Bodin
Lucas Bodin

Reputation: 336

Edit:

    console.log(findFirstMondayMonth('1 jul 2021').toLocaleDateString())
    console.log(findFirstMondayMonth('1 aug 2021').toLocaleDateString())
    console.log(findFirstMondayMonth('2 aug 2021').toLocaleDateString())
    console.log(findFirstMondayMonth('13 aug 2021').toLocaleDateString())

    function findFirstMonday(dateString) {
      let date = new Date(dateString)
      let diffDay = date.getDay() - 1
      if (diffDay == -1) {
        diffDay = 6
      }
      let mondayDate = new Date(dateString);
      mondayDate.setHours(mondayDate.getHours() - diffDay*24)
      return mondayDate
    }
    
    function findFirstMondayMonth(dateString) {
      let date = new Date(dateString)
      if (date.getMonth() == findFirstMonday(date).getMonth()) {
        let dateOneWeekBefore = new Date(dateString)
        dateOneWeekBefore.setHours(dateOneWeekBefore.getHours() - 24 * 7)
        if (date.getMonth() == dateOneWeekBefore.getMonth()) {
          return findFirstMondayMonth(dateOneWeekBefore)
        } else {
          return findFirstMonday(date)
        }
        
      } else {
        let dateOneWeekAfter = new Date(dateString)
        dateOneWeekAfter.setHours(dateOneWeekAfter.getHours() + 24 * 7)
        return findFirstMonday(dateOneWeekAfter)
      }
    }

Sorry for the last answer, I think it was the first monday of week and I don't see Sunday.getMonth() == -1

Upvotes: 2

Peter Lehnhardt
Peter Lehnhardt

Reputation: 4995

I came up with the following code. Some explanations about the general idea:

  1. For a given date get the first date in the month of the given date. This is quite easy by generating a new Date object with day = 1 and the year and month of the given date.
  2. Get the weekday of the first date.
  3. Depending on the weekday of the first date, you must calculate which day number the first Monday has. This number is calculated by ((8 - firstWeekdayInMonth) % 7). You can easily verify yourself, that this always yields a Monday. The modulo is important for Sundays and Mondays, where you would otherwise add 8 and 7 respectively, which would not yield the first Monday anymore.

console.log(findFirstMonday('1 jul 21'))
console.log(findFirstMonday('1 aug 21'))
console.log(findFirstMonday('13 aug 21'))

function findFirstMonday(dateString) {
  let targetDate = new Date(dateString);
  let targetMonth = targetDate.getMonth();
  let targetYear = targetDate.getFullYear();
  let firstDateInMonth = new Date(targetYear, targetMonth, 1);
  let firstWeekdayInMonth = firstDateInMonth.getDay();
  let firstMondayDate = 1 + ((8 - firstWeekdayInMonth) % 7);
  return new Date(targetYear, targetMonth, firstMondayDate).toLocaleDateString();
}

Upvotes: 3

Related Questions