JavaScript:获取两个日期之间的所有月份?

JavaScript:获取两个日期之间的所有月份?,javascript,Javascript,我有两个日期字符串,如下所示: var startDate = '2012-04-01'; var endDate = '2014-11-01'; var dates = ['2012-04-01', '2012-05-01', '2012-06-01' .... '2014-11-01',]; 我想得到一个字符串数组,如下所示: var startDate = '2012-04-01'; var endDate = '2014-11-01'; var dates = ['2012-04-

我有两个日期字符串,如下所示:

var startDate = '2012-04-01';
var endDate = '2014-11-01';
var dates = ['2012-04-01', '2012-05-01', '2012-06-01' .... '2014-11-01',];
我想得到一个字符串数组,如下所示:

var startDate = '2012-04-01';
var endDate = '2014-11-01';
var dates = ['2012-04-01', '2012-05-01', '2012-06-01' .... '2014-11-01',];
到目前为止,这是我得到的,但它相当丑陋:

var startDate = '2012-04-01';
var endDate = '2014-11-01';
var start = new Date(Date.parse(startDate));
var end = new Date(Date.parse(endDate))
var dates = [];
for (var i = start.getFullYear(); i < end.getFullYear() + 1; i++) {
    dates.push(i + '-' + '-01');
}
console.log(dates);
var startDate='2012-04-01';
var endDate='2014-11-01';
var start=新日期(Date.parse(startDate));
var end=新日期(Date.parse(endDate))
var日期=[];
对于(var i=start.getFullYear();i

有更好的办法吗

这将产生所需的输出:

function dateRange(startDate, endDate) {
  var start      = startDate.split('-');
  var end        = endDate.split('-');
  var startYear  = parseInt(start[0]);
  var endYear    = parseInt(end[0]);
  var dates      = [];

  for(var i = startYear; i <= endYear; i++) {
    var endMonth = i != endYear ? 11 : parseInt(end[1]) - 1;
    var startMon = i === startYear ? parseInt(start[1])-1 : 0;
    for(var j = startMon; j <= endMonth; j = j > 12 ? j % 12 || 11 : j+1) {
      var month = j+1;
      var displayMonth = month < 10 ? '0'+month : month;
      dates.push([i, displayMonth, '01'].join('-'));
    }
  }
  return dates;
}

仍然不是一个非常优雅的答案,但是得到了您想要的字符串数组:

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);
var startDate='2012-04-01';
var endDate='2014-11-01';
var开始=新日期(开始日期);
var end=新日期(endDate);
var日期=[];
对于(var i=start.getFullYear();i
var startDate = '2012-04-01';
var endDate = '2014-11-01';
var dates = [];

var d0 = startDate.split('-');
var d1 = endDate.split('-');

for (
    var y = d0[0];
    y <= d1[0];
    y++
) {
    for (
        var m = d0[1];
        m <= 12;
        m++
    ) {
        dates.push(y+"-"+m+"-1");
        if (y >= d1[0] && m >= d1[1]) break;
    };
    d0[1] = 1;
};

console.log(dates);
var startDate='2012-04-01';
var endDate='2014-11-01';
var日期=[];
var d0=起始日期分割('-');
var d1=endDate.split('-');
为了(
变量y=d0[0];
y=d1[1])断裂;
};
d0[1]=1;
};
控制台日志(日期);

您还可以使用优秀的moment.js库:

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');
}

如果加载一个额外的库不是问题,您可以尝试使用AweasomentJS。
提供非常干净和强大的日期操纵

var startDate = moment('2012-04-01');
var endDate = moment('2014-11-01');

var dates = [];
endDate.subtract(1, "month"); //Substract one month to exclude endDate itself

var month = moment(startDate); //clone the startDate
while( month < endDate ) {
    month.add(1, "month");
    dates.push(month.format('YYYY-MM-DD'));
}

console.log(dates);
var startDate=力矩('2012-04-01');
var endDate=力矩('2014-11-01');
var日期=[];
endDate.subtract(1,“month”);//减去一个月以排除endDate本身
var month=时刻(开始日期);//克隆开始日期
而(月<结束日期){
月份。添加(1,“月份”);
推送日期(月格式('YYYY-MM-DD');
}
控制台日志(日期);

jsiddle

一个示例,用于获取给定日期和现在使用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;
};
var getMonths=函数(开始日期){
var日期=[];

对于(var year=startDate.year();year上述所有解决方案都以O(n^2)时间复杂度运行,这不是非常有效。 请参见以下O(n)时间复杂度中的解决方案:

函数getAllMonths(开始,结束){ 让startDate=新日期(开始); 让startYear=startDate.getFullYear(); 让startMonth=startDate.getMonth()+1; 让endDate=新日期(结束); 让endYear=endDate.getFullYear(); 让endMonth=endDate.getMonth()+1; 让countMonth=0; 让countYear=0; 让finalResult=[]; 对于(设a=startYear;a
const getMonths=(fromDate,toDate)=>{
const fromYear=fromDate.getFullYear();
const fromMonth=fromDate.getMonth();
const toYear=toDate.getFullYear();
const toMonth=toDate.getMonth();
常量月数=[];

for(让year=fromYear;year这是我的解决方案,借助数学和O(n)

determinentInterval(开始日期、结束日期){
让startYear=startDate.getFullYear();
让endYear=endDate.getFullYear();
让startMonth=startDate.getMonth()+1;
让endMonth=endDate.getMonth()+1;
让蒙塔蒙特=(月末-开始月)+1+(12*(年末-开始月));
让日期=[];
让currMonth=startMonth;
让currYear=startYear;

对于(设i=0;i,这里有另一个选项:

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;
  }
getRangeOfMonths(开始日期:日期,结束日期:日期){
常量日期=新数组();
const dateCounter=新日期(startDate);
//避免跳过上个月的边缘情况
日期计数器。设置日期(1);
while(日期计数器<结束日期){
推送(`${dateCounter.getFullYear()}-${dateCounter.getMonth()+1}`);
dateCounter.setMonth(dateCounter.getMonth()+1);
}
返回日期;
}

开始日期和结束日期是否始终保证为每月1日午夜?您的解决方案可读性强,易于证明正确(或易于修复)。我怀疑,基于日期对象或朱利安值的“更好”解决方案(逐月推进)实际上会是一个更糟糕的解决方案。它的可读性较差,可能存在错误(对于某些日期输入,例如10月31日加上一个月是多少?),更难证明其正确性。使用moment.js更容易,请检查此解决方案:结果似乎超出了输入变量的范围(您输入了
2014-06-01
,但您的结果一直到
2014-12-01
)@ChrisVilla感谢您指出,
endMonth
计算有一个问题,现在应该解决。请使用moment.js-datetime数学非常棘手且容易出错!如果我们测试它的日期相差几个月,它总是返回12个月。例如
getAllMonths('2018-8-01','2018-11-01'))
返回-
[“2018-8”、“2018-9”、“2018-10”、“2018-11”、“2019-12”、“2019-0”、“2019-1”、“2019-2”、“2019-3”、“2019-4”、“2019-5”、“2019-6”]
看起来我们不需要克隆startDate的
变量。只需执行
结果推送(startDate.format())
谢谢您的帮助,@DimaEscaroda。我已经采纳了您的建议。任何复制此文件的人都应该注意开始日期。添加(1,‘月’)变异startDate对象。如果startDate作为参数传递给函数,您可能希望克隆startDate.moment.js,这样的代码片段才值得。这是momentjs的最佳答案,因为只有在这里,作者才不会更改初始startDate的值。