Цикл 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);
}
Tabares
источник
Что вы должны импортировать, чтобы использовать это?
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
}
jayarjo
источник
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
}
MaxEcho
источник
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 daysOfYear = [];
for (var d = begin; d <= end; d = d + 86400000) {
    daysOfYear.push(new Date(d));
}
Гильерме Симау Коуту
источник
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
Помимо летнего времени, другое граничное условие - это «второй прыжок». Разница в одну секунду имеет значение - даты, конвертированные в миллисекунды, соответствуют первой секунде данного дня. Одна вторая ошибка, и вы приземлились в предыдущий день.
Войтек Крушевский