Boucle JavaScript entre les plages de dates


135

Étant donné deux Date()objets, où l'un est inférieur à l'autre, comment faire une boucle tous les jours entre les dates?

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

}

Ce genre de boucle fonctionnerait-il? Mais comment puis-je ajouter un jour au compteur de boucles?

Merci!

Réponses:


201

Voici un moyen de le faire en utilisant la façon dont l'ajout d'un jour fait passer la date au mois suivant si nécessaire, et sans déranger les millisecondes. L'heure d'été n'est pas non plus un problème.

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

Notez que si vous souhaitez stocker la date, vous devrez en créer une nouvelle (comme ci-dessus avec new Date(d)), sinon vous vous retrouverez avec chaque date stockée étant la valeur finale de ddans la boucle.


Tellement plus lisible que toutes les autres réponses. Ajouter 86400000 millisecondes à chaque boucle n'est pas très lisible.
Owen

1
Soyez prudent avec l'heure d'été. d.getDate () + 1 lorsque d.getDate () = GMT N et d.getDate () + 1 = GMT N - 1 d.getDate () + 1 renvoie le même jour du mois deux fois.
Rafael Fontes

1
Pourquoi faire Date.now()lors de la définition now? new Date() renvoie la date actuelle comme objet par défaut . L'appel Datesans le newconstructeur vous donne juste une chaîne de date que vous convertissez ensuite en objet Date de toute façon?
tatlar

Pour moi, je new Date(2012, 0, 1);ramassais le mauvais jour (un jour avant), cela new Date(Date.UTC(2012, 0, 1))fonctionnait bien.
Tk421

J'ai essayé plusieurs solutions sur Internet. Bizarre, c'est que ça saute parfois quelques jours. Comme 1.12, 2.12, 3.12, 5.12 ... (notez que 4.12 est ignoré) je n'ai aucune idée de pourquoi cela se produit ... Quelqu'un a eu ce problème et a trouvé une solution?
Erik Kubica

73

Basé sur la réponse de Tom Gullen.

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

Que devez-vous importer pour l'utiliser?
DevAllanPer

3
@DevAllanPer rien, Dateest un développeur d'
Dmitri Pisarev

9

Si startDate et endDate sont effectivement des objets de date, vous pouvez les convertir en nombre de millisecondes depuis le 1er janvier 1970 à minuit, comme ceci:

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

Ensuite, vous pouvez faire une boucle de l'un à l'autre en incrémentant loopTime de 86400000 (1000 * 60 * 60 * 24) - nombre de millisecondes en un jour:

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

1
+1, m'a donné assez de travail, ive a inclus la solution de travail dans ma question
Tom Gullen

5
cela ne fonctionne pas lorsque vous passez en boucle au-delà d'un changement d'heure d'été (dans les zones où cela pose un problème). Bonne solution sinon.
tchadgh

3
Vous ne pouvez pas supposer qu'il y a des 86400000secondes dans une journée. Cette boucle est fragile aux changements d'heure d'été et à d'autres conditions de bord.
Jeremy J Starcher

2
Outre DST, une autre condition de bord est "Leap Second". Une seconde différence ne importe - Dates converties en millisecondes correspondent à la première seconde d'un jour donné. Une seconde erreur et vous atterrissez le jour précédent.
Wojtek Kruszewski

9

Je pense avoir trouvé une réponse encore plus simple, si vous vous autorisez à utiliser 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

Voici un code de travail simple, a fonctionné pour moi

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

Sur la base de la réponse de Tabare, j'ai dû ajouter un jour de plus à la fin, car le cycle est coupé avant

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

Si vous voulez un moyen efficace avec des millisecondes:

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

0

Supposons que vous ayez obtenu la date de début et la date de fin de l'interface utilisateur et que vous les ayez stockées dans la variable de portée du contrôleur.

Ensuite, déclarez un tableau qui sera réinitialisé à chaque appel de fonction afin que lors du prochain appel de la fonction, les nouvelles données puissent être stockées.

var dayLabel = [];

N'oubliez pas d'utiliser la nouvelle date (votre variable de départ) car si vous n'utilisez pas la nouvelle date et que vous l'assignez directement à la variable, la fonction setDate changera la valeur de la variable d'origine à chaque itération.

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

-2

Basé sur la réponse de Jayarjo:

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

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

    alert(loopDay);

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

Un commentaire à ce sujet est qu'une comparaison moins que est préférable à! =, Comme quand une boucle sur plusieurs mois pour une raison quelconque, la comparaison! = Ne se déclenche jamais.
Tom Gullen

1
Outre DST, une autre condition de bord est "Leap Second". Une seconde différence ne importe - Dates converties en millisecondes correspondent à la première seconde d'un jour donné. Une seconde erreur et vous atterrissez le jour précédent.
Wojtek Kruszewski
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.