Pesquisa de site

node.js - Javascript - obter array de datas entre 2 datas


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

Eu gostaria que "range" fosse um array de objetos de data, um para cada dia entre as duas datas.

O truque é que ele também deve lidar com os limites de mês e ano.

Resposta #1

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

Aqui está uma demonstração funcional http://jsfiddle.net/jfhartsock/cM3ZU/

Resposta #2

Olhei todos os acima. Acabei escrevendo eu mesmo. Você não precisa do momentjs para isso. Um loop for nativo é suficiente e faz mais sentido porque um loop for existe para contar valores em um intervalo.

Uma Linha:

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

Versão Longa

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

Listar datas entre:

const 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"
*/

Dias desde uma data passada até agora:

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

Resposta #3

Tente isto, lembre-se de incluir 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;
}

Resposta #4

Tive dificuldade em usar as respostas acima. Os intervalos de datas estavam perdendo dias individuais devido à mudança de fuso horário causada pelo horário de verão local (DST). Eu implementei uma versão usando datas em UTC que resolve esse problema:

function dateRange(startDate, endDate, steps = 1) {
  const dateArray = [];
  let currentDate = new Date(startDate);

  while (currentDate <= new Date(endDate)) {
    dateArray.push(new Date(currentDate));
    // Use UTC date to prevent problems with time zones and DST
    currentDate.setUTCDate(currentDate.getUTCDate() + steps);
  }

  return dateArray;
}

const dates = dateRange('2020-09-27', '2020-10-28');
console.log(dates);

Nota: Se um determinado fuso horário ou horário de verão é aplicado depende inteiramente de sua localidade. Substituir isso geralmente não é uma boa ideia. Usar datas em UTC mitiga a maioria dos problemas relacionados ao tempo.

Bônus: Você pode definir o intervalo de tempo para o qual deseja criar carimbos de tempo com o parâmetro opcional steps. Se você quiser carimbos semanais, defina steps como 7.

Resposta #5

Eu uso moment.js e Twix.js, eles fornecem um apoio muito bom para manipulação de data e hora

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

Eu tenho isso rodando em http://jsfiddle.net/Lkzg1bxb/

Resposta #6

Se você estiver usando o moment, então pode usar o 'plugin oficial' deles para intervalos moment-range e então isso se torna trivial.

exemplo de node 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')))

exemplo de navegador 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>

exemplo date fns:

Se você está usando date-fns, então eachDay é seu amigo e você obtém, de longe, a resposta mais curta e concisa:

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>

Resposta #7

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)

Resposta #8

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;

}

Resposta #9

Usando ES6, você tem Array.from, o que significa que você pode escrever uma função realmente elegante, que permite Intervalos dinâmicos (horas, dias, meses).

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

Artigos relacionados