Home > other >  How to get any day's date in a month?
How to get any day's date in a month?

Time:09-17

I need to correct this code to to retrieve date of day selected for a certain month from the select. For example when user select October for month and Tuesday for day, it will list out Tuesday's date on October.

This code works for Monday only.

Full code here: Fiddle

function getAllInstancesOfDayInMonth(fordate, forday) {
    fordate.setDate(1);
    var start  = getStartDay(fordate, forday)
       ,month  = fordate.getMonth()
       ,result = [start];

    while (fordate.getMonth() == month) {
      result.push(new Date(fordate.setDate(fordate.getDate() 7)));
    } 

    return result.slice(0,-1);

    function getStartDay(d, forday) {
     return d.getDay() !=  forday
            ? ( d.setDate( d.getDate()   1 ), getStartDay(d, forday) )
            : new Date(d);
    }

  }
  
  (function () {
 
   document.querySelector('#ddlMonths')
    .addEventListener('change', getDays);
  
   var result = document.querySelector('#result');
  
   result.innerHTML = '<h3>Selected day </h3>';
   result.innerHTML  = getAllInstancesOfDayInMonth(
                           new Date([2015,1,1].join('/')), 1
                        ).join('\n');
  
  function getDays(e){
    var year = this.getAttribute('data-year')
       ,month =  this.options[this.selectedIndex].value
       ,monthstr = this.options[this.selectedIndex].innerHTML;
    
    result.innerHTML = '<h3>all mondays in ' monthstr ' '  year '</h3>';
    result.innerHTML  = getAllInstancesOfDayInMonth(
                           new Date([year,month 1,1].join('/')), 1
                        ).join('\n');
  }
  
  function getAllInstancesOfDayInMonth(fordate, forday) {
    fordate.setDate(2);
    var start  = getStartDay(fordate, forday)
       ,month  = fordate.getMonth()
       ,result = [start];
    
    while (fordate.getMonth() == month) {
      result.push(new Date(fordate.setDate(fordate.getDate() 7)));
    } 
    
    return result.slice(0,-1);
    
    function getStartDay(d, forday) {
     return d.getDay() !=  forday
            ? ( d.setDate( d.getDate()   1 ), getStartDay(d, forday) )
            : new Date(d);
    }
    
  }
  
}())

CodePudding user response:

There are multiple problems in your code. Let's go through them one by one.

The values in the select element for days are not all unique. Fix them as follows:

<select id="ddlDay" class="form-control">
<option value="0">Monday</option>
<option value="1">Tuesday</option>
<option value="2">Wednesday</option>
<option value="3">Thursday</option>
<option value="4">Friday</option>
<option value="5">Saturday</option>
<option value="6">Sunday</option>
</select>

Now on to the javascript...

First of all, your getDays function is only called when you change the months select element, not the days select element. We add the following so that your display will also update when the day is changed:

document.querySelector('#ddlDay')
    .addEventListener('change', getDays);

Inside the getDays function, the user-selected day is never called, so that is why the display is stuck to Monday. We can fix this with the following:

 var year = document.querySelector("#ddlMonths").getAttribute('data-year'),
     month = parseInt(document.querySelector("#ddlMonths").value) 1,
     monthstr = document.querySelector("#ddlMonths option:checked").innerText,
     day = parseInt(document.querySelector("#ddlDay").value) 1,
     daystr = document.querySelector("#ddlDay option:checked").innerText;

This code could definitely use some simplification, but it just works. Notice that the month and day variables should also be converted to the appropriate ints before being fed into the getAllInstancesOfDayInMonth function.

Finally, we update the display and run the above function accordingly:

result.innerHTML = '<h3>all ' daystr 's in ' monthstr ' '  year '</h3>';
result.innerHTML  = getAllInstancesOfDayInMonth(
    new Date([year,month,1].join('/')), day % 7
).join('\n');

I think that should be all. The working fiddle can be found here: https://jsfiddle.net/m9nvekhd

CodePudding user response:

I think you got everything really complicated

const
  myForm   = document.forms['my-form']
, dateYM   = { year: 'numeric', month: 'long'}
, dateLong = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }
, setDays  =_=>
  {
  let dt = new Date(`${myForm.Months.dataset.year}-${myForm.Months.value}-1`)  
  , mRef = dt.getMonth()
    ;
  myForm.result.innerHTML = `<h3>All ${myForm.Day.selectedOptions[0].textContent}in ${dt.toLocaleDateString('en-US',dateYM)} </h3>\n`
    ;
  while ( mRef === dt.getMonth() )
    {
    if ( dt.getDay() == myForm.Day.value )
      myForm.result.innerHTML  = dt.toLocaleDateString('en-US',dateLong)   '\n'
    dt.setDate(dt.getDate()   1) 
  } }
myForm.oninput = setDays

setDays() // init
body {
  font   : 12px/15px normal verdana, arial;
  margin : 1.5em;
  }
output {
  display     : block;
  white-space : pre;
  margin-top  : 2em;
  }
<form name="my-form">
  <select name="Months" data-year="2021">
    <option value="1" > January   </option>
    <option value="2" > February  </option>
    <option value="3" > March     </option>
    <option value="4" > April     </option>
    <option value="5" > May       </option>
    <option value="6" > June      </option>
    <option value="7" > July      </option>
    <option value="8" > August    </option>
    <option value="9" > September </option>
    <option value="10"> October   </option>
    <option value="11"> November  </option>
    <option value="12"> December  </option>
  </select>
  Select a month to retrieve all
  <select id="Day">
    <option value="1" >Monday </option>
    <option value="2" >Tuesday </option>
    <option value="3" >Wednesday </option>
    <option value="4" >Thursday </option>
    <option value="5" >Friday </option>
    <option value="6" >Saturday </option>
    <option value="0" >Sunday </option>  <!-- sunday JS is 0 -->
  </select>
  of it
  <output name="result"></output>
</form>

  • Related