Цикл JavaScript между диапазонами дат


135

Учитывая два Date()объекта, где один меньше другого, как я могу делать циклы каждый день между датами?

for(loopDate = startDate; loopDate < endDate; loopDate += 1)
{

}

Будет ли этот цикл работать? Но как я могу добавить один день к счетчику циклов?

Спасибо!

Ответы:


201

Вот способ сделать это, используя способ добавления одного дня, при котором дата переносится на следующий месяц, если это необходимо, и не возиться с миллисекундами. Летнее время тоже не проблема.

var now = new Date();
var daysOfYear = [];
for (var d = new Date(2012, 0, 1); d <= now; d.setDate(d.getDate() + 1)) {
    daysOfYear.push(new Date(d));
}

Обратите внимание, что если вы хотите сохранить дату, вам нужно будет создать новую (как указано выше с помощью new Date(d)), иначе вы в конечном итоге получите каждую сохраненную дату, являющуюся конечным значением dв цикле.


Так гораздо более читабельно, чем все остальные ответы. При добавлении 86400000 миллисекунд каждая петля не очень читаема.
Оуэн

1
Будьте осторожны с летним временем. d.getDate () + 1, когда d.getDate () = GMT N и d.getDate () + 1 = GMT N - 1. d.getDate () + 1 дважды возвращает один и тот же день месяца.
Рафаэль Фонтес

1
Почему Date.now()при определении now? new Date() возвращает текущую дату как объект по умолчанию . Вызов Dateбез newконструктора просто дает вам строку Date, которую вы потом конвертируете в объект Date?
Tatlar

Для меня new Date(2012, 0, 1);подбирал неправильный день (за день до этого), new Date(Date.UTC(2012, 0, 1))работал нормально.
Tk421

Я пробовал несколько решений в Интернете. Странно, что иногда пропускает несколько дней. Как 1.12, 2.12, 3.12, 5.12 ... (обратите внимание, что 4.12 пропущен) Я понятия не имею, почему это происходит ... Кто-нибудь получил эту проблему и нашел решение?
Эрик Кубица

73

Основано на ответе Тома Гуллена.

var start = new Date("02/05/2013");
var end = new Date("02/10/2013");


var loop = new Date(start);
while(loop <= end){
   alert(loop);           

   var newDate = loop.setDate(loop.getDate() + 1);
   loop = new Date(newDate);
}

Что вы должны импортировать, чтобы использовать это?
DevAllanPer

3
@DevAllanPer ничто, Dateглобальный объект developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Дмитрий Писарев

9

Если startDate и endDate действительно являются объектами даты, вы можете преобразовать их в число миллисекунд с полуночи 1 января 1970 года, например:

var startTime = startDate.getTime(), endTime = endDate.getTime();

Затем вы можете переходить от одного к другому, увеличивая loopTime на 86400000 (1000 * 60 * 60 * 24) - количество миллисекунд в одном дне:

for(loopTime = startTime; loopTime < endTime; loopTime += 86400000)
{
    var loopDay=new Date(loopTime)
    //use loopDay as you wish
}

1
+1, дал мне достаточно для работы, я включил рабочее решение в мой вопрос
Том Гуллен

5
это не работает при цикле после изменения летнего времени (в областях, где это является проблемой). Хорошее решение в противном случае.
Чад

3
Вы не можете предполагать, что есть 86400000секунды в дне. Этот цикл хрупок для изменений летнего времени и других граничных условий.
Джереми Дж. Старчер

2
Помимо летнего времени, другое граничное условие - это «второй прыжок». Разница в одну секунду имеет значение - даты, конвертированные в миллисекунды, соответствуют первой секунде данного дня. Одна вторая ошибка, и вы приземлились в предыдущий день.
Войтек Крушевский

9

Я думаю, что нашел еще более простой ответ, если вы позволите себе использовать Moment.js :

// cycle through last five days, today included
// you could also cycle through any dates you want, mostly for
// making this snippet not time aware
const currentMoment = moment().subtract(4, 'days');
const endMoment = moment().add(1, 'days');
while (currentMoment.isBefore(endMoment, 'day')) {
  console.log(`Loop at ${currentMoment.format('YYYY-MM-DD')}`);
  currentMoment.add(1, 'days');
}
<script src="https://cdn.jsdelivr.net/npm/moment@2/moment.min.js"></script>


5

Вот простой рабочий код, у меня работает

var from = new Date(2012,0,1);
var to = new Date(2012,1,20);
    
// loop for every day
for (var day = from; day <= to; day.setDate(day.getDate() + 1)) {
      
   // your day is here

}


2
var start = new Date("2014-05-01"); //yyyy-mm-dd
var end = new Date("2014-05-05"); //yyyy-mm-dd

while(start <= end){

    var mm = ((start.getMonth()+1)>=10)?(start.getMonth()+1):'0'+(start.getMonth()+1);
    var dd = ((start.getDate())>=10)? (start.getDate()) : '0' + (start.getDate());
    var yyyy = start.getFullYear();
    var date = dd+"/"+mm+"/"+yyyy; //yyyy-mm-dd

    alert(date); 

    start = new Date(start.setDate(start.getDate() + 1)); //date increase by 1
}

1

Основываясь на ответе Табаре, мне пришлось добавить еще один день в конце, так как цикл сокращается до

var start = new Date("02/05/2013");
var end = new Date("02/10/2013");
var newend = end.setDate(end.getDate()+1);
var end = new Date(newend);
while(start < end){
   alert(start);           

   var newDate = start.setDate(start.getDate() + 1);
   start = new Date(newDate);
}


0

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

Затем объявите массив, который будет сбрасываться при каждом вызове функции, чтобы при следующем вызове функции новые данные могли быть сохранены.

var dayLabel = [];

Не забудьте использовать новую дату (вашу начальную переменную), потому что, если вы не используете новую дату и напрямую назначаете ее переменной, функция setDate будет изменять значение исходной переменной в каждой итерации`

for (var d = new Date($scope.startDate); d <= $scope.endDate; d.setDate(d.getDate() + 1)) {
                dayLabel.push(new Date(d));
            }

-2

Основываясь на ответе Джаярджо:

var loopDate = new Date();
loopDate.setTime(datFrom.valueOf());

while (loopDate.valueOf() < datTo.valueOf() + 86400000) {

    alert(loopDay);

    loopDate.setTime(loopDate.valueOf() + 86400000);
}

Один комментарий к этому заключается в том, что сравнение меньше, чем предпочтительно! =, Так как при циклическом выполнении нескольких месяцев по какой-то причине сравнение! = Никогда не срабатывает.
Том Гуллен

1
Помимо летнего времени, другое граничное условие - это «второй прыжок». Разница в одну секунду имеет значение - даты, конвертированные в миллисекунды, соответствуют первой секунде данного дня. Одна вторая ошибка, и вы приземлились в предыдущий день.
Войтек Крушевский
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.