Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a specify date in every month in Javascript?

I need to find this month, previous month and the next month of a specific date.

For example, date was set to 31 of every month, what I expect to get the date is 2018-02-28, 2018-03-31 and 2018-04-30. For those dates which has no 31, than it becomes the day before.

And finally generate 2 period, 2018-02-28 to 2018-03-29, 2018-03-30 to 2018-04-31. I don't know how to handle feb and the month which less than 31.

var d = new Date();
var tyear = d.getFullYear(); //2018
var tmonth = d.getMonth();  //2  
new Date(2018, tmonth-1, 31);//output 2018-03-02 not what I wanted
like image 202
Wayne Fung Avatar asked Mar 13 '18 20:03

Wayne Fung


People also ask

How do I create a specific date in JavaScript?

We can create a date object by passing the Date object a timestamp number in milliseconds. For example, new Date(1572840117245) . When we create a date object by passing it 0 milliseconds, it will return the date object for Jan 01 1970 05:30:00 .

What does the JavaScript date () function do?

Date methods allow you to get and set the year, month, day, hour, minute, second, and millisecond of date objects, using either local time or UTC (universal, or GMT) time.

What does the getMonth () method of the date object return?

getMonth() The getMonth() method returns the month in the specified date according to local time, as a zero-based value (where zero indicates the first month of the year).

What value is returned by getMonth in April in JavaScript?

Javascript date getMonth() method returns the month in the specified date according to local time. The value returned by getMonth() is an integer between 0 and 11.


2 Answers

A simple algorithm is to add months to the original date, and if the new date is wrong, set it to the last day of the previous month. Keeping the original date values unmodified helps, e.g.

/* @param {Date} start - date to start
** @param {number} count - number of months to generate dates for
** @returns {Array} monthly Dates from start for count months
*/
function getMonthlyDates(start, count) {
  var result = [];
  var temp;
  var year = start.getFullYear();
  var month = start.getMonth();
  var startDay = start.getDate();
  for (var i=0; i<count; i++) {
    temp = new Date(year, month + i, startDay);
    if (temp.getDate() != startDay) temp.setDate(0);
    result.push(temp);
  }
  return result;
}

// Start on 31 Jan in leap year
getMonthlyDates(new Date(2016,0,31), 4).forEach(d => console.log(d.toString()));
// Start on 31 Jan not in leap year
getMonthlyDates(new Date(2018,0,31), 4).forEach(d => console.log(d.toString()));

// Start on 30 Jan
getMonthlyDates(new Date(2018,0,30), 4).forEach(d => console.log(d.toString()));
// Start on 5 Jan
getMonthlyDates(new Date(2018,0,5), 4).forEach(d => console.log(d.toString()));
like image 196
RobG Avatar answered Oct 19 '22 05:10

RobG


I think you're going to need an array with 12 numbers in it. Each number is the amount of days in each month and the numbers in the array go in order (first number is 31 because January has 31 days, second is 28 or 29 for Feb), etc. Then you'll get the month number from your input date and look in the array at the number corresponding to the month number +/- 1.

You'll then need to construct a date for the previous month and the next month based on the number of days in the current month.

See comments inline:

let daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

document.getElementById("date").addEventListener("input", function(){
  console.clear();
  
  // Create new Date based on value in date picker
  var selectedDate = new Date(this.value + 'T00:00');

  var year = selectedDate.getYear();

  // Determine if it is a leap year (Feb has 29 days) and update array if so.
  if (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) {
    daysInMonths[1] = 29;
  }

  var selectedDateMonth = selectedDate.getMonth();
     
  // Get previous month number (if current month is January, get December)
  let prevMonth = selectedDateMonth > 0 ? selectedDateMonth - 1 : 11;
  
  let prevMonthDate = null;
  
  // If selected date is last day of month...
  if(selectedDate.getDate() === daysInMonths[selectedDateMonth]){
    // Create new date that takes the selected date and subtracts the correct amount of
    // days from it based on a lookup in the array.
    var newDate1 = new Date(selectedDate.getTime());
    prevMonthDate = 
     new Date(newDate1.setDate(selectedDate.getDate() - daysInMonths[selectedDateMonth]));
  } else {
    // Create a new date that is last month and one day earlier
    var newDate2 = new Date(selectedDate.getTime());
    prevMonthDate = 
      new Date(new Date(newDate2.setDate(selectedDate.getDate() - 1))
        .setMonth(selectedDate.getMonth() - 1));
  }
  
  // Get next month (if current month is December, get January
  let nextMonth = selectedDateMonth < 11 ? selectedDateMonth + 1 : 0;  
  
  let nextMonthDate = null;
  
  // Same idea for next month, but add instead of subtract.
  
  // If selected date is last day of month...
  if(selectedDate.getDate() === daysInMonths[selectedDateMonth]){
    var newDate3 = new Date(selectedDate.getTime());
    nextMonthDate = 
     new Date(newDate3.setDate(selectedDate.getDate() + daysInMonths[selectedDateMonth + 1]));
  } else {
    var newDate4 = new Date(selectedDate.getTime());
    nextMonthDate = new Date(new Date(newDate4.setDate(selectedDate.getDate() + 1)).setMonth(selectedDate.getMonth() + 1));
  }  

  console.log("Last month date: " + prevMonthDate.toLocaleDateString());
  console.log("Next month date: " + nextMonthDate.toLocaleDateString());  
});
<p>Pick a date: <input type="date" id="date"></p>
like image 43
Scott Marcus Avatar answered Oct 19 '22 05:10

Scott Marcus