2015-05-26 6 views
1

У меня есть две даты строки, как это: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 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); 

Есть ли лучший способ? JSFiddle.

+1

Даты начала и окончания всегда гарантированно будут полночь 1-го числа месяца? – thatidiotguy

+1

Ваше решение легко читается и легко доказывается корректно (или легко фиксируется). Я подозреваю, что «лучшее» решение, основанное на объектах Date или юлианских значениях, которое продвигается месяц за месяцем, на самом деле окажется худшим решением. Это было бы менее читаемым, вероятно, прослушиваемым (для определенных дат ввода, например, 31 октября плюс один месяц?), И гораздо сложнее доказать его правильность. – jarmod

+0

Проще всего использовать moment.js, пожалуйста, проверьте это решение: http://stackoverflow.com/questions/29466944/how-to-list-all-month-between-2-dates-with-moment-js – Andres

ответ

8

Это должно произвести желаемый результат:

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

Просто назовите ее с существующим форматом даты:

dateRange('2013-11-01', '2014-06-01') 
// ["2013-11-01", "2013-12-01", "2014-01-01", "2014-02-01", "2014-03-01", "2014-04-01", "2014-05-01", "2014-06-01", "2014-07-01", "2014-08-01", "2014-09-01", "2014-10-01", "2014-11-01", "2014-12-01"] 
+0

Результаты похоже, превышают диапазон входной переменной (вы вводите '2014-06-01', но ваш результат доходит до' 2014-12-01') –

+0

@ChrisVilla благодарит за указание на то, что было вопрос с вычислением 'endMonth', который должен быть разрешен сейчас. –

0

Еще не очень элегантный ответ, но приходит в массив строк, которые вы хотите :

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 ссылка здесь: http://jsfiddle.net/8kut035a/

1

Вы справляетесь с «логическими» прыжками, поэтому вам действительно не нужна временная артефакт. Так что это простая задача подсчета:

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); 
4

Вы также можете использовать прекрасную библиотеку 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." 
} 

var currentDate = startDate.clone(); 

while (startDate.isBefore(endDate)) { 
    result.push(currentDate.format("YYYY-MM-01")); 
    startDate.add(1, 'month'); 
} 

JSFiddle

1

При загрузке дополнительного библиотеки не является проблемой, вы всегда можно попробовать удивительный MomentJS.
Дает очень чистые и эффективные манипуляции с датами.

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

JSFiddle here

0

пример, чтобы получить все первые дни месяцев между указанной датой, и теперь с помощью 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; 
}; 
Смежные вопросы