Ciclo JavaScript tra intervalli di date


135

Dati due Date()oggetti, in cui uno è inferiore all'altro, come faccio a scorrere ogni giorno tra le date?

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

}

Questo tipo di loop funzionerebbe? Ma come posso aggiungere un giorno al contatore dei loop?

Grazie!

Risposte:


201

Ecco un modo per farlo sfruttando il modo in cui l'aggiunta di un giorno fa sì che la data passi al mese successivo, se necessario, e senza perdere tempo con i millisecondi. Neanche l'ora legale è un problema.

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

Nota che se vuoi memorizzare la data, dovrai crearne una nuova (come sopra con new Date(d)), altrimenti finirai con ogni data memorizzata come valore finale dnel ciclo.


Molto più leggibile di tutte le altre risposte. L'aggiunta di 86400000 millisecondi ogni ciclo non è molto leggibile.
Owen,

1
Prestare attenzione all'ora legale. d.getDate () + 1 quando d.getDate () = GMT N e d.getDate () + 1 = GMT N - 1 d.getDate () + 1 restituisce due volte lo stesso giorno del mese.
Rafael Fontes,

1
Perché fare Date.now()quando si definisce now? new Date() restituisce la data corrente come oggetto per impostazione predefinita . Chiamare Datesenza il newcostruttore ti dà solo una stringa Date che poi converti in un oggetto Date?
tatlar,

Per me new Date(2012, 0, 1);stava raccogliendo il giorno sbagliato (un giorno prima), ha new Date(Date.UTC(2012, 0, 1))funzionato bene.
Tk421,

Ho provato più soluzioni su Internet. Strano è che a volte salta qualche giorno. Come 1.12, 2.12, 3.12, 5.12 ... (nota che 4.12 è saltato) non ho idea del perché accada ... Qualcuno ha questo problema e ha trovato una soluzione?
Erik Kubica,


9

Se startDate e endDate sono effettivamente oggetti data, puoi convertirli in numero di millisecondi dalla mezzanotte del 1 gennaio 1970, in questo modo:

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

Quindi è possibile eseguire il loop da uno all'altro loopTime incrementale di 86400000 (1000 * 60 * 60 * 24) - numero di millisecondi in un giorno:

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

1
+1, mi ha dato abbastanza su cui lavorare, tra cui ho incluso la soluzione di lavoro nella mia domanda
Tom Gullen,

5
questo non funziona quando si passa in rassegna un cambio dell'ora legale (nelle aree in cui questo è un problema). Buona soluzione altrimenti.
chadgh,

3
Non puoi presumere che ci siano 86400000secondi in un giorno. Questo circuito è fragile rispetto ai cambiamenti dell'ora legale e ad altre condizioni del bordo.
Jeremy J Starcher,

2
Oltre all'ora legale, un'altra condizione limite è "Leap Second". A differenza di un secondo fa materia - Date convertiti millisecondi corrispondono alla prima seconda di un dato giorno. Un secondo errore e atterri il giorno precedente.
Wojtek Kruszewski,

9

Penso di aver trovato una risposta ancora più semplice, se ti permetti di usare 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

Qui semplice codice di lavoro, ha funzionato per me

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

Sulla base della risposta di Tabare, alla fine ho dovuto aggiungere un altro giorno, poiché il ciclo è stato interrotto in precedenza

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

Se vuoi un modo efficiente con millisecondi:

var daysOfYear = [];
for (var d = begin; d <= end; d = d + 86400000) {
    daysOfYear.push(new Date(d));
}

0

Supponiamo che tu abbia ottenuto la data di inizio e di fine dall'interfaccia utente e che sia stata memorizzata nella variabile ambito nel controller.

Quindi dichiarare un array che verrà reimpostato su ogni chiamata di funzione in modo che sulla chiamata successiva per la funzione sia possibile memorizzare i nuovi dati.

var dayLabel = [];

Ricorda di usare la nuova data (la tua variabile iniziale) perché se non usi la nuova data e la assegni direttamente alla variabile, la funzione setDate cambierà il valore della variabile originale in ogni iterazione`

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

-2

Basato sulla risposta di Jayarjo:

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

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

    alert(loopDay);

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

Un commento per questo è che è preferibile un confronto minore rispetto a! =, Poiché quando si esegue il ciclo su più mesi per qualche motivo il confronto! = Non si attiva mai.
Tom Gullen,

1
Oltre all'ora legale, un'altra condizione limite è "Leap Second". A differenza di un secondo fa materia - Date convertiti millisecondi corrispondono alla prima seconda di un dato giorno. Un secondo errore e atterri il giorno precedente.
Wojtek Kruszewski,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.