Search code examples
javascriptcalendar

February Month not showing correctly in my yearly calendar


I am trying to show a section in my website with either 3 months or 1 month away from the current month and depending on the screen size. User can then loop through the other months with the arrows in the screen, month by month. Until now it seems to be working correctly. However I am struggling to find why when reaching February = (fevrier here) month, it is not correctly posted, and instead it shows March (Mars here) even though the calendar show 28 or 29 days characteristic to February. Could somebody please find the reason why this is happening and explain it please? Below is a reproducible snippet.

Thank you!

const calendar = document.querySelector('.reservation_calendar')

let date = new Date()
let dday = date.getDay()
let dmonth = date.getMonth()
let year = date.getFullYear()
let dateCounterLimit=3

let monthArray = ['Janvier','Fevrier','Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'decembre']


let dayone = new Date(year, dmonth, 1).getDay();
 
// Get the last date of the month
let lastdate = new Date(year, dmonth+1, 0).getDate();

// Get the day of the last date of the month
let dayend = new Date(year, dmonth, lastdate).getDay();

// Get the last date of the previous month
let monthlastdate = new Date(year, dmonth, 0).getDate();




function myCallBack(){
returnValue()
window.addEventListener('resize', appenDate)
window.onload = appenDate()
}


const returnValue = () =>{
    if(window.innerWidth<650){
        return {
            dateCounterLimit: 1,
        }
    }else{
        return {
            dateCounterLimit: 3,
         }
    }
};

const appenDate = () =>{
    calendar.innerHTML = ''
    dateCounterLimit=returnValue().dateCounterLimit
    console.log(dateCounterLimit)
    let i = document.createElement('i')
    i.className = 'bi bi-arrow-left-circle'
    calendar.appendChild(i)
    let i1 = document.createElement('i')
    i1.className = 'bi bi-arrow-right-circle'
    calendar.appendChild(i1)
    const icon = document.querySelectorAll('.reservation_calendar .bi')
    icon.forEach(icon=>icon.addEventListener('click',(e)=>{
        let target = e.target
        if(target.classList.contains('bi-arrow-right-circle')){
            dmonth++
            removeMonths()
            checkDateCalendarLimit(dmonth)
        }else{
            dmonth--
            removeMonths()
            checkDateCalendarLimit(dmonth)
        }
    }))
checkDateCalendarLimit(dmonth)

}


function checkDateCalendarLimit(dmonth){
    if(dateCounterLimit==1){
        console.log({dmonth})
        appendCalendar(dmonth)
    }
    else{
        for(let i=0; i<dateCounterLimit;i++){
            dmonth+=1
            console.log({dmonth})
            appendCalendar(dmonth)
        }
    }
}


function appendCalendar(param){
    let wrapper = document.createElement('div')
    let DateSpanWrapperDiv = document.createElement('div')
    DateSpanWrapperDiv.className = 'DateSpanWrapperDiv'
    let month_parag = document.createElement('p')
    month_parag.className = "the_month"
    calendar.appendChild(wrapper)
    wrapper.appendChild(month_parag)
    wrapper.appendChild(DateSpanWrapperDiv)
    wrapper.setAttribute('id', `dateWrapper_${param}`)
    wrapper.className = "dateWrapperDiv"
    let lastdate = new Date(year, param+1, 0).getDate();
    let dyear = date.getFullYear()

    if ((param) < 0 || (param) > 11) {
        date = new Date(year, param, new Date().getDate());
        dyear = date.getFullYear() 
        console.log({dyear})
        param = date.getMonth();
        month_parag.innerHTML = `${monthArray[param]} ${dyear}`
    }else{
        date = new Date()
        domth = date.getMonth()
        month_parag.innerHTML = `${monthArray[param]} ${year}`
    }

    for(let i=1; i<=lastdate; i++){
        let dateSpan = document.createElement('span')
        dateSpan.innerHTML = i
        DateSpanWrapperDiv.appendChild(dateSpan)
    }
}


function removeMonths(){
    const dateWrapperDiv = document.querySelectorAll('.dateWrapperDiv')
    dateWrapperDiv.forEach(elem=>elem.remove())
}



myCallBack()
.reservation_calendar {
    position: relative;
    display: flex;
    flex-direction: row;
    justify-content: center;
    gap: 2rem;
  }

 .reservation_calendar .bi-arrow-left-circle{
    position: absolute;
    left: 0%;
    top: 50%;
  }

.reservation_calendar .bi-arrow-right-circle{
    position: absolute;
    right: 0%;
    top: 50%;
  }

.reservation_calendar .dateWrapperDiv{
    display: flex;
    flex-direction: column;
}

.reservation_calendar .dateWrapperDiv p{
    display: grid;
    place-items: center;
}

.reservation_calendar .dateWrapperDiv .DateSpanWrapperDiv {
    display: grid;
    grid-template-columns: repeat(7,1fr);
    gap: 0.5rem;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
<div class="reservation_calendar"></div>

I tried to console.log the value of months at each step and still have the correct values. Can't find what I am missing here.


Solution

  • It's probably because of modulo 12... I changed the param (month) to "true modulo" so month is in range 0 - 11. Also number of months divided by 12 is the year diff from current year.

      var diffYear = Math.floor(param / 12)
      param = (param % 12 + 12) % 12
    
      date = new Date()
      domth = date.getMonth()
      month_parag.innerHTML = `${monthArray[param]} ${year + diffYear}`
    
    

    const calendar = document.querySelector('.reservation_calendar')
    
    let date = new Date()
    let dday = date.getDay()
    let dmonth = date.getMonth()
    let year = date.getFullYear()
    let dateCounterLimit = 3
    
    let monthArray = ['Janvier', 'Fevrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'decembre']
    
    
    let dayone = new Date(year, dmonth, 1).getDay();
    
    // Get the last date of the month
    let lastdate = new Date(year, dmonth + 1, 0).getDate();
    
    // Get the day of the last date of the month
    let dayend = new Date(year, dmonth, lastdate).getDay();
    
    // Get the last date of the previous month
    let monthlastdate = new Date(year, dmonth, 0).getDate();
    
    
    
    
    function myCallBack() {
      returnValue()
      window.addEventListener('resize', appenDate)
      window.onload = appenDate()
    }
    
    
    const returnValue = () => {
      if (window.innerWidth < 650) {
        return {
          dateCounterLimit: 1,
        }
      } else {
        return {
          dateCounterLimit: 3,
        }
      }
    };
    
    const appenDate = () => {
      calendar.innerHTML = ''
      dateCounterLimit = returnValue().dateCounterLimit
      let i = document.createElement('i')
      i.className = 'bi bi-arrow-left-circle'
      calendar.appendChild(i)
      let i1 = document.createElement('i')
      i1.className = 'bi bi-arrow-right-circle'
      calendar.appendChild(i1)
      const icon = document.querySelectorAll('.reservation_calendar .bi')
      icon.forEach(icon => icon.addEventListener('click', (e) => {
        let target = e.target
        if (target.classList.contains('bi-arrow-right-circle')) {
          dmonth++
          removeMonths()
          checkDateCalendarLimit(dmonth)
        } else {
          dmonth--
          removeMonths()
          checkDateCalendarLimit(dmonth)
        }
      }))
      checkDateCalendarLimit(dmonth)
    
    }
    
    
    function checkDateCalendarLimit(dmonth) {
      if (dateCounterLimit == 1) {
        appendCalendar(dmonth)
      } else {
        for (let i = 0; i < dateCounterLimit; i++) {
          dmonth += 1
          appendCalendar(dmonth)
        }
      }
    }
    
    
    function appendCalendar(param) {
    
      let wrapper = document.createElement('div')
      let DateSpanWrapperDiv = document.createElement('div')
      DateSpanWrapperDiv.className = 'DateSpanWrapperDiv'
      let month_parag = document.createElement('p')
      month_parag.className = "the_month"
      calendar.appendChild(wrapper)
      wrapper.appendChild(month_parag)
      wrapper.appendChild(DateSpanWrapperDiv)
      wrapper.setAttribute('id', `dateWrapper_${param}`)
      wrapper.className = "dateWrapperDiv"
      let lastdate = new Date(year, param + 1, 0).getDate();
      let dyear = date.getFullYear()
    
      var diffYear = Math.floor(param / 12)
      param = (param % 12 + 12) % 12
    
      date = new Date()
      domth = date.getMonth()
      month_parag.innerHTML = `${monthArray[param]} ${year + diffYear}`
    
    
      for (let i = 1; i <= lastdate; i++) {
        let dateSpan = document.createElement('span')
        dateSpan.innerHTML = i
        DateSpanWrapperDiv.appendChild(dateSpan)
      }
    }
    
    
    function removeMonths() {
      const dateWrapperDiv = document.querySelectorAll('.dateWrapperDiv')
      dateWrapperDiv.forEach(elem => elem.remove())
    }
    
    
    
    myCallBack()
    .reservation_calendar {
      position: relative;
      display: flex;
      flex-direction: row;
      justify-content: center;
      gap: 2rem;
    }
    
    .reservation_calendar .bi-arrow-left-circle {
      position: absolute;
      left: 0%;
      top: 50%;
    }
    
    .reservation_calendar .bi-arrow-right-circle {
      position: absolute;
      right: 0%;
      top: 50%;
    }
    
    .reservation_calendar .dateWrapperDiv {
      display: flex;
      flex-direction: column;
    }
    
    .reservation_calendar .dateWrapperDiv p {
      display: grid;
      place-items: center;
    }
    
    .reservation_calendar .dateWrapperDiv .DateSpanWrapperDiv {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: 0.5rem;
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
    <div class="reservation_calendar"></div>