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!

Tom Gullen
la source

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.

David Johnstone
la source
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);
}
Tabares
la source
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
}
Jayarjo
la source
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>

vvo
la source
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

}

Amr Ibrahim
la source
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
la source
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);
}
Carlos Vizcaya Savchenco
la source
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));
}
Guilherme Simão Couto
la source
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));
            }
Utkarsh Joshi
la source
-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);
}
Tom Gullen
la source
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