JavaScript-Schleife zwischen Datumsbereichen

135

Date()Wie kann ich bei zwei Objekten, bei denen eines kleiner als das andere ist, jeden Tag eine Schleife zwischen den Daten durchlaufen?

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

}

Würde diese Art von Schleife funktionieren? Aber wie kann ich einen Tag zum Schleifenzähler hinzufügen?

Vielen Dank!

Tom Gullen
quelle

Antworten:

200

Hier ist eine Möglichkeit, dies zu tun, indem Sie die Methode zum Hinzufügen eines Tages verwenden, um das Datum bei Bedarf auf den nächsten Monat zu verschieben, ohne mit Millisekunden herumzuspielen. Sommerzeit ist auch kein Thema.

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

Beachten Sie, dass Sie, wenn Sie das Datum speichern möchten, ein neues erstellen müssen (wie oben mit new Date(d)), da sonst jedes gespeicherte Datum der Endwert din der Schleife ist.

David Johnstone
quelle
So viel lesbarer als alle anderen Antworten. Das Hinzufügen von 86400000 Millisekunden zu jeder Schleife ist nicht sehr gut lesbar.
Owen
1
Seien Sie vorsichtig mit Sommerzeit. d.getDate () + 1, wenn d.getDate () = GMT N und d.getDate () + 1 = GMT N - 1 d.getDate () + 1 zweimal denselben Monatstag zurückgibt.
Rafael Fontes
1
Warum Date.now()beim Definieren now? new Date() Gibt standardmäßig das aktuelle Datum als Objekt zurück . Wenn Sie Dateohne den newKonstruktor aufrufen, erhalten Sie nur eine Datumszeichenfolge, die Sie dann trotzdem in ein Datumsobjekt konvertieren.
Tatlar
Für mich new Date(2012, 0, 1);war es gut, den falschen Tag (einen Tag zuvor) new Date(Date.UTC(2012, 0, 1))abzuholen.
Tk421
Ich habe mehrere Lösungen im Internet ausprobiert. Seltsam ist, dass es manchmal einige Tage überspringt. Wie 1.12, 2.12, 3.12, 5.12 ... (beachten Sie, dass 4.12 übersprungen wird) Ich habe keine Ahnung, warum es passiert ... Hat jemand dieses Problem und eine Lösung gefunden?
Erik Kubica
73

Basierend auf Tom Gullens Antwort.

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
quelle
Was müssen Sie importieren, um dies zu verwenden?
DevAllanPer
3
@DevAllanPer nichts, Dateist ein globales Objekt developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Dmitri Pisarev
9

Wenn startDate und endDate tatsächlich Datumsobjekte sind, können Sie sie seit dem 1. Januar 1970 um Mitternacht in die Anzahl der Millisekunden konvertieren.

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

Dann könnten Sie eine Schleife von einer zur anderen inkrementieren und die Schleifenzeit um 86400000 (1000 * 60 * 60 * 24) erhöhen - Anzahl der Millisekunden an einem Tag:

for(loopTime = startTime; loopTime < endTime; loopTime += 86400000)
{
    var loopDay=new Date(loopTime)
    //use loopDay as you wish
}
Jayarjo
quelle
1
+1, gab mir genug, um daran zu arbeiten, ich habe die Arbeitslösung in meine Frage aufgenommen
Tom Gullen
5
Dies funktioniert nicht, wenn Sie eine Änderung der Sommerzeit durchlaufen (in Bereichen, in denen dies ein Problem darstellt). Ansonsten gute Lösung.
Chadgh
3
Sie können nicht davon ausgehen , gibt es 86400000Sekunden in einem Tag. Diese Schleife ist anfällig für Änderungen der Sommerzeit und andere Randbedingungen.
Jeremy J Starcher
2
Neben der Sommerzeit ist eine weitere Randbedingung "Schaltsekunde". Ein Unterschied von einer Sekunde spielt eine Rolle - In Millisekunden umgerechnete Daten entsprechen der ersten Sekunde eines bestimmten Tages. Ein zweiter Fehler und Sie landen am Vortag.
Wojtek Kruszewski
9

Ich denke, ich habe eine noch einfachere Antwort gefunden, wenn Sie sich erlauben, Moment.js zu verwenden :

// 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>

vvo
quelle
5

Hier hat einfacher Arbeitscode für mich funktioniert

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

}

Amr Ibrahim
quelle
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
quelle
1

Basierend auf Tabares Antwort musste ich am Ende noch einen Tag hinzufügen, da der Zyklus zuvor gekürzt wurde

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);
}
Carlos Vizcaya Savchenco
quelle
0

Wenn Sie einen effizienten Weg mit Millisekunden suchen:

var daysOfYear = [];
for (var d = begin; d <= end; d = d + 86400000) {
    daysOfYear.push(new Date(d));
}
Guilherme Simão Couto
quelle
0

Nehmen wir an, Sie haben das Start- und Enddatum von der Benutzeroberfläche abgerufen und in der Bereichsvariablen im Controller gespeichert.

Deklarieren Sie dann ein Array, das bei jedem Funktionsaufruf zurückgesetzt wird, damit beim nächsten Aufruf der Funktion die neuen Daten gespeichert werden können.

var dayLabel = [];

Denken Sie daran, ein neues Datum (Ihre Startvariable ) zu verwenden, da die Funktion setDate den ursprünglichen Variablenwert in jeder Iteration ändert, wenn Sie das neue Datum nicht verwenden und es direkt der Variablen zuweisen

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

Basierend auf Jayarjos Antwort:

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

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

    alert(loopDay);

    loopDate.setTime(loopDate.valueOf() + 86400000);
}
Tom Gullen
quelle
Ein Kommentar dazu ist, dass ein weniger als Vergleich gegenüber! = Bevorzugt wird, da bei einer Schleife über mehrere Monate aus irgendeinem Grund der! = Vergleich niemals ausgelöst wird.
Tom Gullen
1
Neben der Sommerzeit ist eine weitere Randbedingung "Schaltsekunde". Ein Unterschied von einer Sekunde spielt eine Rolle - In Millisekunden umgerechnete Daten entsprechen der ersten Sekunde eines bestimmten Tages. Ein zweiter Fehler und Sie landen am Vortag.
Wojtek Kruszewski