Цикл 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?
татлар

Для мене 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();

Тоді ви можете перевести цикл з одного на інший нарощування циклу на 86400000 (1000 * 60 * 60 * 24) - кількість мілісекунд за один день:

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

1
+1, дав мені достатньо для роботи, ive включив робоче рішення у своє запитання
Tom Gullen

5
це не спрацьовує, коли циклічне перемикання часу минулої зміни часу (в районах, де це проблема). Гарне рішення в іншому випадку.
чад

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

2
Крім DST, ще одна умова краю - "Leap Second". Різниця на одну секунду має значення - дати, перетворені в мілісекунди, відповідають першій секунді даного дня. Одна секунда помилки, і ви приземляєтеся в попередній день.
Войтек Крушевський

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
Крім DST, ще одна умова краю - "Leap Second". Різниця на одну секунду має значення - дати, перетворені в мілісекунди, відповідають першій секунді даного дня. Одна секунда помилки, і ви приземляєтеся в попередній день.
Войтек Крушевський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.