web-dev-qa-db-fra.com

Javascript - Obtenir un tableau de dates entre 2 dates

var range = getDates(new Date(), new Date().addDays(7));

J'aimerais que "range" soit un tableau d'objets de date, un pour chaque jour compris entre les deux dates.

Le truc, c'est qu'il devrait également gérer les limites de mois et d'année.

Merci.

97
Scott
function (startDate, endDate, addFn, interval) {

 addFn = addFn || Date.prototype.addDays;
 interval = interval || 1;

 var retVal = [];
 var current = new Date(startDate);

 while (current <= endDate) {
  retVal.Push(new Date(current));
  current = addFn.call(current, interval);
 }

 return retVal;

}
11
Scott
Date.prototype.addDays = function(days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

function getDates(startDate, stopDate) {
    var dateArray = new Array();
    var currentDate = startDate;
    while (currentDate <= stopDate) {
        dateArray.Push(new Date (currentDate));
        currentDate = currentDate.addDays(1);
    }
    return dateArray;
}

Voici un fonctionnel demohttp://jsfiddle.net/jfhartsock/cM3ZU/

139
John Hartsock

Essayez ceci, n'oubliez pas d'inclure le moment js,

function getDates(startDate, stopDate) {
    var dateArray = [];
    var currentDate = moment(startDate);
    var stopDate = moment(stopDate);
    while (currentDate <= stopDate) {
        dateArray.Push( moment(currentDate).format('YYYY-MM-DD') )
        currentDate = moment(currentDate).add(1, 'days');
    }
    return dateArray;
}
33
Mohammed Safeer

J'utilise moment.js et Twix.js ils fournissent un très bon support pour la gestion de la date et l'heure

var itr = moment.twix(new Date('2012-01-15'),new Date('2012-01-20')).iterate("days");
var range=[];
while(itr.hasNext()){
    range.Push(itr.next().toDate())
}
console.log(range);

J'ai cette course sur http://jsfiddle.net/Lkzg1bxb/

24
Ahmed Aswani
var boxingDay = new Date("12/26/2010");
var nextWeek  = boxingDay*1 + 7*24*3600*1000;

function getDates( d1, d2 ){
  var oneDay = 24*3600*1000;
  for (var d=[],ms=d1*1,last=d2*1;ms<last;ms+=oneDay){
    d.Push( new Date(ms) );
  }
  return d;
}

getDates( boxingDay, nextWeek ).join("\n");
// Sun Dec 26 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Mon Dec 27 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Tue Dec 28 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Wed Dec 29 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Thu Dec 30 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Fri Dec 31 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Sat Jan 01 2011 00:00:00 GMT-0700 (Mountain Standard Time)
12
Phrogz

J'ai regardé tous ceux ci-dessus. J'ai fini par écrire moi-même. Vous n'avez pas besoin de moments pour cela . Une boucle for native suffit et semble plus logique, car une boucle for existe pour compter les valeurs d'une plage.

Bon mot:

var getDaysArray = function(s,e) {for(var a=[],d=s;d<=e;d.setDate(d.getDate()+1)){ a.Push(new Date(d));}return a;};

Version longue

var getDaysArray = function(start, end) {
    for(var arr=[],dt=start; dt<=end; dt.setDate(dt.getDate()+1)){
        arr.Push(new Date(dt));
    }
    return arr;
};

Liste des dates entre:

var daylist = getDaysArray(new Date("2018-05-01"),new Date("2018-07-01"));
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
/*
Output: 
    "2018-05-01
    2018-05-02
    2018-05-03
    ...
    2018-06-30
    2018-07-01"
*/

Jours d'une date passée à maintenant:

var daylist = getDaysArray(new Date("2018-05-01"),new Date());
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
7
enesn

J'utilise la solution @Mohammed Safeer depuis un certain temps et j'ai apporté quelques améliorations. Utiliser des dates formatées est une mauvaise pratique lorsque vous travaillez dans vos contrôleurs. moment().format() doit être utilisé uniquement à des fins d'affichage dans les vues. Rappelez-vous également que moment().clone() garantit la séparation des paramètres d'entrée, ce qui signifie que les dates d'entrée ne sont pas modifiées. Je vous encourage fortement à utiliser moment.js lorsque vous travaillez avec des dates.

Usage:

  • Indiquez les dates moment.js sous forme de valeurs pour les paramètres startDate, endDate
  • Le paramètre interval est facultatif et la valeur par défaut est 'days'. Utilisez des intervalles gérés par la méthode .add() (moment.js). Plus de détails ici
  • Le paramètre total est utile pour spécifier des intervalles en minutes. La valeur par défaut est 1.

Invoquer:

var startDate = moment(),
    endDate = moment().add(1, 'days');

getDatesRangeArray(startDate, endDate, 'minutes', 30);

Une fonction:

var getDatesRangeArray = function (startDate, endDate, interval, total) {
    var config = {
            interval: interval || 'days',
            total: total || 1
        },
        dateArray = [],
        currentDate = startDate.clone();

    while (currentDate < endDate) {
        dateArray.Push(currentDate);
        currentDate = currentDate.clone().add(config.total, config.interval);
    }

    return dateArray;
};
6
Adrian Moisa

Je travaillais récemment avec moment.js, en suivant le truc ..

function getDateRange(startDate, endDate, dateFormat) {
        var dates = [],
            end = moment(endDate),
            diff = endDate.diff(startDate, 'days');

        if(!startDate.isValid() || !endDate.isValid() || diff <= 0) {
            return;
        }

        for(var i = 0; i < diff; i++) {
            dates.Push(end.subtract(1,'d').format(dateFormat));
        }

        return dates;
    };
    console.log(getDateRange(startDate, endDate, dateFormat));

Le résultat serait:

["09/03/2015", "10/03/2015", "11/03/2015", "12/03/2015", "13/03/2015", "14/03/2015", "15/03/2015", "16/03/2015", "17/03/2015", "18/03/2015"]
4
gor181

Je viens juste de trouver cette question, le moyen le plus simple de le faire est d'utiliser l'instant:

Vous devez d'abord installer le moment et la plage de moments:

const Moment = require('moment');
const MomentRange = require('moment-range');
const moment = MomentRange.extendMoment(Moment);

const start = moment()
const end = moment().add(2, 'months')
const range = moment.range(start, end)
const arrayOfDates = Array.from(range.by('days'))
console.log(arrayOfDates)
4
Irfy

En utilisant ES6, vous avez Array.from, ce qui signifie que vous pouvez écrire une fonction très élégante, permettant des intervalles dynamiques (heures, jours, mois).

function getDates(startDate, endDate, interval) {
const duration = endDate - startDate;
const steps = duration / interval;
return Array.from({length: steps+1}, (v,i) => new Date(startDate.valueOf() + (interval * i)));
}
const startDate = new Date(2017,12,30);
const endDate = new Date(2018,1,3);
const dayInterval = 1000 * 60 * 60 * 24; // 1 day
const halfDayInterval = 1000 * 60 * 60 * 12; // 1/2 day

console.log("Days", getDates(startDate, endDate, dayInterval));
console.log("Half Days", getDates(startDate, endDate, halfDayInterval));

3
digiguru

Voici une ligne qui ne nécessite aucune bibliothèque au cas où vous ne voudriez pas créer une autre fonction. Il suffit de remplacer startDate (à deux endroits) et endDate (qui sont des objets js date) par vos variables ou valeurs de date. Bien sûr, vous pouvez l’envelopper dans une fonction si vous préférez

Array(Math.floor((endDate - startDate) / 86400000) + 1).fill().map((_, idx) => (new Date(startDate.getTime() + idx * 86400000)))
3
ti994a

Si vous utilisez moment, vous pouvez utiliser leur "plug-in officiel" pour les plages moment-range et cela devient alors trivial.

Exemple de nœud moment-range:

const Moment = require('moment');
const MomentRange = require('moment-range');
const moment = MomentRange.extendMoment(Moment);

const start = new Date("11/30/2018"), end = new Date("09/30/2019")
const range = moment.range(moment(start), moment(end));

console.log(Array.from(range.by('day')))

Exemple de navigateur moment-range:

window['moment-range'].extendMoment(moment);

const start = new Date("11/30/2018"), end = new Date("09/30/2019")
const range = moment.range(moment(start), moment(end));

console.log(Array.from(range.by('day')))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-range/4.0.1/moment-range.js"></script>

exemple date fns:

Si vous utilisez date-fns then eachDay est votre ami et vous obtenez de loin la réponse la plus courte et la plus concise:

console.log(dateFns.eachDay(
  new Date(2018, 11, 30),
  new Date(2019, 30, 09)
))
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.29.0/date_fns.min.js"></script>

2
Akrion

d3js fournit de nombreuses fonctions pratiques et comprend d3.time pour une manipulation aisée de la date

https://github.com/d3/d3-time

Pour votre demande spécifique:

UTC

var range = d3.utcDay.range(new Date(), d3.utcDay.offset(new Date(), 7));

ou heure locale

var range = d3.timeDay.range(new Date(), d3.timeDay.offset(new Date(), 7));

gamme sera un tableau d'objets de date qui tombent sur la première valeur possible pour chaque jour

vous pouvez changer heure à heure heure, heure etc. pour obtenir les mêmes résultats à des intervalles différents

2
Russell Thompson

J'utilise une boucle while simple pour calculer les dates entre 

var start = new Date("01/05/2017");
var end = new Date("06/30/2017");
var newend = end.setDate(end.getDate()+1);
var end = new Date(newend);
while(start < end){
   console.log(new Date(start).getTime() / 1000); // unix timestamp format
   console.log(start); // ISO Date format          
   var newDate = start.setDate(start.getDate() + 1);
   start = new Date(newDate);
}

1
KARTHIKEYAN.A
var listDate = [];
var startDate ='2017-02-01';
var endDate = '2017-02-10';
var dateMove = new Date(startDate);
var strDate = startDate;

while (strDate < endDate){
  var strDate = dateMove.toISOString().slice(0,10);
  listDate.Push(strDate);
  dateMove.setDate(dateMove.getDate()+1);
};
console.log(listDate);

//["2017-02-01", "2017-02-02", "2017-02-03", "2017-02-04", "2017-02-05", "2017-02-06", "2017-02-07", "2017-02-08", "2017-02-09", "2017-02-10"]
1
Công Thắng

Une fonction:

  var dates = [],
      currentDate = startDate,
      addDays = function(days) {
        var date = new Date(this.valueOf());
        date.setDate(date.getDate() + days);
        return date;
      };
  while (currentDate <= endDate) {
    dates.Push(currentDate);
    currentDate = addDays.call(currentDate, 1);
  }
  return dates;
};

Usage:

var dates = getDatesRange(new Date(2019,01,01), new Date(2019,01,25));                                                                                                           
dates.forEach(function(date) {
  console.log(date);
});

J'espère que ça vous aide

0
Hiu D

Cela peut aider quelqu'un, 

Vous pouvez obtenir la sortie de ligne à partir de cela et formater l'objet row_date à votre guise.

var from_date = '2016-01-01';
var to_date = '2016-02-20';

var dates = getDates(from_date, to_date);

console.log(dates);

function getDates(from_date, to_date) {
  var current_date = new Date(from_date);
  var end_date     = new Date(to_date);

  var getTimeDiff = Math.abs(current_date.getTime() - end_date.getTime());
  var date_range = Math.ceil(getTimeDiff / (1000 * 3600 * 24)) + 1 ;

  var weekday = ["Sun", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
  var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
  var dates = new Array();

  for (var i = 0; i <= date_range; i++) {
     var getDate, getMonth = '';

     if(current_date.getDate() < 10) { getDate = ('0'+ current_date.getDate());}
     else{getDate = current_date.getDate();}

    if(current_date.getMonth() < 9) { getMonth = ('0'+ (current_date.getMonth()+1));}
    else{getMonth = current_date.getMonth();}

    var row_date = {day: getDate, month: getMonth, year: current_date.getFullYear()};
    var fmt_date = {weekDay: weekday[current_date.getDay()], date: getDate, month: months[current_date.getMonth()]};
    var is_weekend = false;
    if (current_date.getDay() == 0 || current_date.getDay() == 6) {
        is_weekend = true;
    }
    dates.Push({row_date: row_date, fmt_date: fmt_date, is_weekend: is_weekend});
    current_date.setDate(current_date.getDate() + 1);
 }
 return dates;
}

https://Gist.github.com/pranid/3c78f36253cbbc6a41a859c5d718f362.js

0
Praneeth Nidarshan

_ {Note: Je suis conscient que cette solution est légèrement différente de la solution demandée, mais je pense que beaucoup la trouveront utile. 

Si vous souhaitez trouver chaque "x" intervalles (jours, mois, années, etc.) entre deux dates, les packages moment.js et les extensions moment-range permettent cette fonctionnalité.

Par exemple, pour trouver chaque 30e jour entre deux dates:

window['moment-range'].extendMoment(moment);

var dateString = "2018-05-12 17:32:34.874-08";
var start  = new Date(dateString);
var end    = new Date();
var range1 = moment.range(start, end);
var arrayOfIntervalDates = Array.from(range1.by('day', { step: 30 }));

arrayOfIntervalDates.map(function(intervalDate){
  console.log(intervalDate.format('YY-M-DD'))
});
0
Stone

La solution de @ softvar, mais avec l'option des dates de travail

/**
 * Returns array of working days between two dates.
 *
 * @param {string} startDate
 *   The start date in yyyy-mm-dd format.
 * @param {string} endDate
 *   The end date in yyyy-mm-dd format.
 * @param {boolean} onlyWorkingDays
 *   If true only working days are returned. Default: false
 *
 * @return {array}
 *   Array of dates in yyyy-mm-dd string format.
 */
function getDates(startDate, stopDate, onlyWorkingDays) {
  let doWd = typeof onlyWorkingDays ==='undefined' ? false : onlyWorkingDays;

  let dateArray = [];  
  let dayNr;
  let runDateObj = moment(startDate);  
  let stopDateObj = moment(stopDate);

  while (runDateObj <= stopDateObj) {
    dayNr = runDateObj.day();
    if (!doWd || (dayNr>0 && dayNr<6)) {
     dateArray.Push(moment(runDateObj).format('YYYY-MM-DD'));  
    }

    runDateObj = moment(runDateObj).add(1, 'days');
  }
  return dateArray;
}
0
koosvdkolk

Voici une méthode prédéfinie qui accepte les dates ou les chaînes Moment ou un mélange en tant qu'entrées et génère un tableau de dates sous forme de dates Moment. Si vous ne souhaitez pas que les dates Moment soient générées, modifiez ce que la méthode map() renvoie.

const moment = require('moment');

// ...

/**
 * @param {string|import('moment').Moment} start
 * @param {string|import('moment').Moment} end
 * @returns {import('moment').Moment[]}
 */
const getDateRange = (start, end) => {
  const s = moment.isMoment(start) ? start : moment(start);
  const e = moment.isMoment(end) ? end : moment(end);
  return [...Array(1 + e.diff(s, 'days')).keys()].map(n => moment(s).add(n, 'days'));
};
0
Guy