1

I have two date e.g 1/04/2017 - 30/06/2017

I want to find the first and last date of every month between the date range above.

Like this -

1/04/2017 - 30/04/2017 1/05/2017 - 31/05/2017 1/06/2017 - 30/06/2017

This is because I want to use this solution in fullcalendar for recurring events, so that I can add the date ranges in the below code -

batches.push({
    id        : item.id,
    title     : item.title.textCapitalize(),
    start     : item.start_time,
    end       : item.end_time,
    dow       : item.weekdays,
    ranges    : 
    [
      {
        start   : '2017-04-01', //all of april
        end     : '2017-04-20',
      },
      {
        start   : '2017-05-01', //all of may
        end     : '2017-05-31',
      },
      {
        start   : '2017-06-01', //all of june
        end     : '2017-06-30',
      },
    ],
    backgroundColor : backgroundColor,
    borderColor     : backgroundColor
});
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Deepak Panwar
  • 160
  • 10

2 Answers2

3

Here is a working version

const aDay = 24 * 60 * 60 * 1000;
const pad = num => ("0" + num).slice(-2);

const formatDate = d => d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate());

const getRange = range => {
  ranges = [];

  console.log("start", range.start, "end", range.end)

  for (var i = range.start.getTime(), end = range.end.getTime(); i <= end;) {
    var first = new Date(i), last = new Date(first.getFullYear(), first.getMonth() + 1, 0); // last day of the month
    ranges.push({
      start: formatDate(first),
      end: formatDate(last)
    })
    i = last.getTime() + aDay;
    // if (!confirm(formatDate(new Date(i)))) break
  }
  return ranges;
}

let range = { // your range
  start: new Date(2019, 0, 1, 15, 0, 0, 0), // remember month is 0 based
  end: new Date(2020, 0, 1, 15, 0, 0, 0) // use 15:00 to help DST and Timzones yesterday
};
console.log(getRange(range))
range = { // your range
  start: new Date(2019, 1, 28, 15, 0, 0, 0), // remember month is 0 based
  end: new Date(2019, 4, 1, 15, 0, 0, 0) // use 15:00 to help DST and Timzones yesterday
};
console.log(getRange(range))
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • To be completely correct as the start and end dates are included in ranges, the terminal for loop condition must be `end + aDay`. Without this, if the last day is the first day of the next month, it will be merged in the previous month. Try with `2019-01-01` to `2020-01-01`. Without the `i <= end + aDay`, we still have 12 ranges, instead of 13 and the last range is a bit weird. :) – glihm Dec 06 '19 at 07:28
  • 1
    @glihm I rewrote the code but did not change the logic. My previous logic and new logic both got from start to end inclusive - HOWEVER I added time to make sure the timezone was not ruining the dates – mplungjan Dec 06 '19 at 08:59
0

Here we get month first and last dates which are actual dates, also we get dates which are present in other months but are first and last date if we see in calendar, this dates are marked as virtual date.

$("#picker").monthpicker({
  onSelect:function(dateText, inst) {
        $("#picker").monthpicker('setDate', $("#picker").monthpicker('getDate'));
            var clicked_date = $(this).monthpicker('getDate'),
                clicked_year = clicked_date.getFullYear(),
                clicked_month = clicked_date.getMonth();
       GetMonthStartEndDate(clicked_year, clicked_month);
              $(this).blur();
    }
})

function GetMonthStartEndDate(_year, _month) {
    var month = _month;
    var year = _year;
    var firstDay_actual = new Date(year, month, 1);
     document.getElementById("ademo").innerHTML = firstDay_actual;
    var firstDay_virtual = new Date(firstDay_actual.setDate(firstDay_actual.getDate() - firstDay_actual.getDay()));
   document.getElementById("demo").innerHTML = firstDay_virtual;
   

    var lastDay_actual = new Date(year, month + 1, 0);
    document.getElementById("ademo1").innerHTML = lastDay_actual;
    var lastDay_virtual = new Date(lastDay_actual.setDate(lastDay_actual.getDate() + (6 - lastDay_actual.getDay())));
 document.getElementById("demo1").innerHTML = lastDay_virtual;
  
}
.act{
color:green;
}

.vrt{
color:yellow;
}
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://rawgit.com/zorab47/jquery.ui.monthpicker/master/jquery.ui.monthpicker.js"></script>


Select month : <input type="text" id="picker">

<br> <br>
<p class="act"> Actual dates: </p>

<p id="ademo"></p>
<p id="ademo1"></p>

<p class="vrt"> Virtual dates: </p>

<p id="demo"></p>
<p id="demo1"></p>
dn_pdih
  • 11
  • 3