[removed] get all months between two dates?

后端 未结 10 536
醉酒成梦
醉酒成梦 2020-12-09 10:12

I have two date strings like this:

var startDate = \'2012-04-01\';
var endDate = \'2014-11-01\';

And I want to end up with an array of stri

相关标签:
10条回答
  • 2020-12-09 10:25

      const getMonths = (fromDate, toDate) => {
        const fromYear = fromDate.getFullYear();
        const fromMonth = fromDate.getMonth();
        const toYear = toDate.getFullYear();
        const toMonth = toDate.getMonth();
        const months = [];
        for(let year = fromYear; year <= toYear; year++) {
          let month = year === fromYear ? fromMonth : 0;
          const monthLimit = year === toYear ? toMonth : 11;
          for(; month <= monthLimit; month++) {
            months.push({ year, month })
          }
        }
        return months;
      }
    const sample = getMonths(new Date('2022-07-28'), new Date('2023-03-20'));
    console.log(sample);
    document.write('check the console output');

    https://jsfiddle.net/xfayoqvs/

    0 讨论(0)
  • 2020-12-09 10:25

    Still not a very elegant answer, but arrives at the array of strings you want:

    var startDate = '2012-04-01';
    var endDate = '2014-11-01';
    var start = new Date(startDate);
    var end = new Date(endDate);
    var dates = [];
    for (var i = start.getFullYear(); i < end.getFullYear() + 1; i++) {
        for (var j = 1; j <= 12; j++) {
          if (i === end.getFullYear() && j === end.getMonth() + 3) {
            break;
          }
          else if (i === 2012 && j < 4){
            continue;
          }
          else if (j < 10) {
            var dateString = [i, '-', '0' + j, '-','01'].join('');
            dates.push(dateString)
            }
          else {
            var dateString = [i, '-', j, '-','01'].join('');
            dates.push(dateString);
            }
        }
    }
    console.log(dates);
    

    jsfiddle link here: http://jsfiddle.net/8kut035a/

    0 讨论(0)
  • 2020-12-09 10:26

    Here is another option:

    getRangeOfMonths(startDate: Date, endDate: Date) {
        const dates = new Array<string>();
        const dateCounter = new Date(startDate);
        // avoids edge case where last month is skipped
        dateCounter.setDate(1);
        while (dateCounter < endDate) {
          dates.push(`${dateCounter.getFullYear()}-${dateCounter.getMonth() + 1}`);
          dateCounter.setMonth(dateCounter.getMonth() + 1);
        }
        return dates;
      }
    
    0 讨论(0)
  • 2020-12-09 10:29

    All solutions above run in O(n^2) time complexity, which is not very efficient. See below solution in O(n) time complexity:

    function getAllMonths(start, end){	
    	let startDate = new Date(start);
    	let startYear = startDate.getFullYear();
    	let startMonth = startDate.getMonth()+1;
    	
    	let endDate = new Date(end);
    	let endYear = endDate.getFullYear();
    	let endMonth = endDate.getMonth()+1;
    	
    	let countMonth = 0;
    	let countYear = 0;
    	let finalResult = [];
    
    	for(let a=startYear; a<=endYear; a++){
    
    		if(startYear<endYear){
    			if(countYear==0){
    				countMonth += 12-startMonth;
                }else 
    			if(countYear>0){
    				countMonth += 12;
                }
    			countYear+=1;
    			startYear++;
            }else 
    		if(startYear==endYear){
    			countMonth+=endMonth;
            }
        }
    	for(let i=startMonth; i<=countMonth+startMonth; i++){
    		finalResult.push(startDate.getFullYear()+(Math.floor(i/12)) + "-" + Math.round(i%13) + "-" + "01");
        }
    	return finalResult;
    }
    
    getAllMonths('2016-04-01', '2018-01-01');

    Might share a much more simpler code

    0 讨论(0)
  • 2020-12-09 10:30

    An example to get all first days of months between a given date and now using moment.js.

       var getMonths = function (startDate) {
        var dates = [];
        for (var year = startDate.year(); year <= moment().year(); year++) {
            var endMonth = year != moment().year() ? 11 : moment().month();
            var startMonth = year === startDate.year() ? startDate.month() : 0;
            for (var currentMonth = startMonth; currentMonth <= endMonth; currentMonth = currentMonth > 12 ? currentMonth % 12 || 11 : currentMonth + 1) {
                var month = currentMonth + 1;
                var displayMonth = month < 10 ? '0' + month : month;
                dates.push([year, displayMonth, '01'].join('-'));
            }
        }
        return dates;
    };
    
    0 讨论(0)
  • 2020-12-09 10:38

    You can also use the excellent moment.js library:

    var startDate = moment('2012-04-01');
    var endDate = moment('2014-11-01');
    
    var result = [];
    
    if (endDate.isBefore(startDate)) {
        throw "End date must be greated than start date."
    }      
    
    while (startDate.isBefore(endDate)) {
        result.push(startDate.format("YYYY-MM-01"));
        startDate.add(1, 'month');
    }
    

    JSFiddle

    0 讨论(0)
提交回复
热议问题