Javascript - Abrufen einer Reihe von Daten zwischen zwei Daten

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

Ich möchte, dass "Bereich" eine Reihe von Datumsobjekten ist, eines für jeden Tag zwischen den beiden Daten.

Der Trick ist, dass es auch Monats- und Jahresgrenzen behandeln sollte.

Scott Klarenbach
quelle

Antworten:

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

Hier ist eine funktionale Demo http://jsfiddle.net/jfhartsock/cM3ZU/

John Hartsock
quelle
2
Danke John. Ich habe meistens deine verwendet, aber du hast einen byRef-Fehler, da currentDate nicht auf das Array verschoben werden kann oder du am Ende ein Array von n Elementen hast, alles als letztes Datum. Das Ändern in currentDate = new Date (currentDate) funktioniert.
Scott Klarenbach
Dies ist in Ordnung für das zukünftige Datum, aber wenn ich am vergangenen Datum wie 30 Tage zuvor arbeite, wo soll ich den obigen Code ändern, um nur Datum und nicht Uhrzeit zu erhalten.
Vaibhav Kulkarni
@vaibhavkulkarni Sie können einfach den addays () -Prototyp umkehren und die while-Schleife ändern. Darüber hinaus sind Kommentare nicht der richtige Ort, um eine neue Frage zu stellen.
John Hartsock
Sollten wir die Zeit besser von startDateund entfernen endDate? Denn wenn startDatedie Zeit später als stopDatedie Zeit ist, wird sie nicht stopDatein das Ergebnis einbezogen, oder?
Hp93
@ Hp93 Ich weiß nicht genau, wovon du sprichst. Wenn Sie die von mir bereitgestellte Geige ausführen, werden Sie feststellen, dass sie diese Situation abdeckt.
John Hartsock
55

Versuchen Sie dies, denken Sie daran, 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;
}
Mohammed Safeer
quelle
Nur eine kleine Verbesserung: Kurzschreibweise zum Erstellen von Arrays wird empfohlen. var dateArray = [];Details hier
Adrian Moisa
Es ist die neue Art, Arrays zu definieren, und ich nehme an, es ist kürzer / sauberer.
Mohammed Safeer
1
Wichtiger Fix : var currentDate = moment(startDate);Wenn Sie diese Methode zweimal im selben Moment verwenden. Sie werden verwirrt sein, warum sie nur beim ersten Mal funktioniert. Dies liegt daran, dass Javascripts Objekte als Referenz übergeben, sodass die Funktion das startDate zweimal verwendet (was bereits mutiert ist). Durch das Patchen des obigen Fixes wird sichergestellt, dass Sie mit neuen und einzigartigen Moment-js-Objekten im Funktionsumfang arbeiten. Überprüfen Sie diese Geige
Adrian Moisa
50

Ich habe alle oben gesehen. Am Ende habe ich mich selbst geschrieben. Sie brauchen dafür keine Momente . Eine native for-Schleife ist ausreichend und am sinnvollsten, da eine for-Schleife vorhanden ist, um Werte in einem Bereich zu zählen.

Einzeiler:

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

Lange Version

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

Liste Daten dazwischen:

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

Tage von einem vergangenen Datum bis jetzt:

var daylist = getDaysArray(new Date("2018-05-01"),new Date());
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
enesn
quelle
Was ist, wenn Sie alle von Ihnen angegebenen Tage abrufen möchten getDaysArray? Nicht die Tage dazwischen.
Jonjie
Vielen Dank! genau das, was ich brauchte, ohne Abhängigkeiten. :)
Mpsyp
2
Diese Funktion bearbeitet das Datum der Quelleneingabe. :) Ich habe es getestet.
Hamed Taheri
4
@ HamedTaheri-ja, aber das kann durch die Zuweisung einer Kopie fixiert werden Anfang an dt statt beginnen selbst, zB for (var arr=[], dt=new Date(start), ...). ;-)
RobG
gut funktionieren, aber schade, dass eine for (;;) - Schleife für die Softwarewartung nicht so lesbar ist, wenn Sie mit vielen anderen Personen arbeiten.
Victor
27

Ich benutze moment.js und Twix.js, sie bieten eine sehr gute Unterstützung für die Manpulation von Datum und Uhrzeit

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

Ich habe dies auf http://jsfiddle.net/Lkzg1bxb/ laufen.

Ahmed Aswani
quelle
Ich habe alle damit verbundenen Dateien heruntergeladen, aber es zeigt immer noch den Fehler TypeError: moment.twix ist keine Funktion
vaibhav kulkarni
Möglicherweise müssen Sie die Bibliotheken einschließen. In nodejs sieht es so aus: var moment = require ('moment'); erfordern ('twix');
Dr. Bala Soundararaj
18
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)
Phrogz
quelle
3
Um sicher zu gehen, sollten Sie im Gegensatz zu den oben genannten normalerweise eine Tagesmitte wählen, um geringfügige Abweichungen aufgrund der Sommerzeit zu vermeiden.
Phrogz
Ich wünschte, Sie würden dem Code auch eine Änderung zur Tagesmitte hinzufügen.
Hühner
15
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;

}
Scott Klarenbach
quelle
1
Dies würde einfrieren, wenn Sie Daten in falscher Reihenfolge
angeben
11

Wenn Sie moment verwenden, können Sie das "offizielle Plugin" für Bereiche verwenden, moment-rangeund dann wird dies trivial.

Beispiel für einen Momentbereichsknoten:

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

Beispiel für einen Momentbereichsbrowser:

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>

Datum fns Beispiel:

Wenn Sie verwenden, date-fnsdann eachDayist Ihr Freund und Sie erhalten bei weitem die kürzeste und prägnanteste Antwort:

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>

Akrion
quelle
8

Ich bin gerade auf diese Frage gestoßen. Der einfachste Weg, dies zu tun, ist die Verwendung von moment:

Sie müssen zuerst Moment und Momentbereich installieren:

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)
Irfy
quelle
6

Ich verwende seit einiger Zeit die @ Mohammed Safeer-Lösung und habe einige Verbesserungen vorgenommen. Die Verwendung formatierter Daten ist eine schlechte Vorgehensweise bei der Arbeit in Ihren Controllern. moment().format()sollte nur für Anzeigezwecke in Ansichten verwendet werden. Denken Sie auch daran, dass moment().clone()die Trennung von Eingabeparametern gewährleistet ist, sodass die Eingabedaten nicht geändert werden. Ich empfehle Ihnen dringend, moment.js zu verwenden, wenn Sie mit Datumsangaben arbeiten.

Verwendung:

  • Geben Sie moment.js Daten als Werte für startDate, endDateParameter
  • intervalDer Parameter ist optional und standardmäßig 'Tage'. Verwenden Sie Intervalle, die von der .add()Methode (moment.js) unterstützt werden. Weitere Details hier
  • totalDer Parameter ist nützlich, wenn Intervalle in Minuten angegeben werden. Der Standardwert ist 1.

Aufrufen:

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

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

Funktion:

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;
};
Adrian Moisa
quelle
6

Mit ES6 haben Sie Array.from, was bedeutet, dass Sie eine wirklich elegante Funktion schreiben können, die dynamische Intervalle (Stunden, Tage, Monate) ermöglicht.

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

Digiguru
quelle
2
"Elegant" hängt von Ihrer Sichtweise ab. new Date(2017,12,30)ist der 30. Januar 2018, für mich beginnt der Datumsbereich am 29. Januar 2018. Nicht alle Tage sind 8,64 bis 7 ms (24 Stunden) lang, an denen die Sommerzeit beobachtet wird. ;-)
RobG
5

Ich habe kürzlich mit moment.js gearbeitet, gefolgt von dem Trick ..

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

Ergebnis wäre:

["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"]
gor181
quelle
3
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"]
Công Thắng
quelle
1
Bitte fügen Sie weitere Beschreibungen und / oder Informationen zu Ihrer Antwort und zur Lösung des gestellten Problems hinzu, damit andere es leicht verstehen können, ohne um Klarstellung zu bitten
koceeng
Ich finde, dass dies aus irgendeinem Grund den 31.03.2016 überspringt!
Woodhead92
1
Sie sollten nicht varvorher strDatein der while-Schleife haben!
Boris Yakubchik
2

d3js bietet viele praktische Funktionen und enthält d3.time für einfache Datumsmanipulationen

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

Für Ihre spezielle Anfrage:

Koordinierte Weltzeit

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

oder Ortszeit

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

Bereich ist ein Array von Datumsobjekten, die auf den ersten möglichen Wert für jeden Tag fallen

Sie können timeDay in timeHour, timeMonth usw. ändern, um dieselben Ergebnisse in unterschiedlichen Intervallen zu erzielen

Russell Thompson
quelle
2

Hier ist ein Einzeiler, für den keine Bibliotheken erforderlich sind, falls Sie keine weitere Funktion erstellen möchten. Ersetzen Sie einfach startDate (an zwei Stellen) und endDate (js Datumsobjekte) durch Ihre Variablen oder Datumswerte. Natürlich können Sie es in eine Funktion einwickeln, wenn Sie es vorziehen

Array(Math.floor((endDate - startDate) / 86400000) + 1).fill().map((_, idx) => (new Date(startDate.getTime() + idx * 86400000)))
ti994a
quelle
Dies berücksichtigt keine Änderungen der Sommerzeit / Standard-Sparzeit. Einige Tage sind länger und andere kürzer
Mike
2

Ich benutze diese Funktion

function getDatesRange(startDate, stopDate) {
    const ONE_DAY = 24*3600*1000;
    var days= [];
    var currentDate = new Date(startDate);
    while (currentDate <= stopDate) {
        days.push(new Date (currentDate));
        currentDate = currentDate - 1 + 1 + ONE_DAY;
    }
    return days;
}
IdontCareAboutReputationPoints
quelle
2

Ich verwende eine einfache while-Schleife, um die Zwischendaten zu berechnen

var start = new Date("01/05/2017");
var end = new Date("06/30/2017");
var newend = end.setDate(end.getDate()+1);
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);
}

KARTHIKEYAN.A
quelle
1

Hinweis: Ich bin mir bewusst, dass dies etwas anders ist als die angeforderte Lösung, aber ich denke, viele werden es nützlich finden.

Wenn Sie jedes "x" -Intervall (Tage, Monate, Jahre usw.) zwischen zwei Datumsangaben suchen möchten , aktivieren moment.js und die Erweiterungspakete für den Momentbereich diese Funktionalität.

So finden Sie beispielsweise jeden 30. Tag zwischen zwei Daten :

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'))
});
Stein
quelle
1
  1. Generieren Sie eine Reihe von Jahren:

    const DAYS = () => {
     const days = []
     const dateStart = moment()
     const dateEnd = moment().add(30, days')
     while (dateEnd.diff(dateStart, days') >= 0) {
      days.push(dateStart.format(‘D'))
      dateStart.add(1, days')
     }
     return days
    }
    console.log(DAYS())
  2. Generieren Sie ein Array für einen Monat:

            const MONTHS = () => {
             const months = []
             const dateStart = moment()
             const dateEnd = moment().add(12, month')
             while (dateEnd.diff(dateStart, months') >= 0) {
              months.push(dateStart.format(‘M'))
              dateStart.add(1, month')
             }
             return months
            }
            console.log(MONTHS())
  3. Generieren Sie ein Arrays für Tage:

            const DAYS = () => {
             const days = []
             const dateStart = moment()
             const dateEnd = moment().add(30, days')
             while (dateEnd.diff(dateStart, days') >= 0) {
              days.push(dateStart.format(‘D'))
              dateStart.add(1, days')
             }
             return days
            }
            console.log(DAYS())
elnaz nasiri
quelle
0

Dies kann jemandem helfen,

Sie können die Zeilenausgabe daraus abrufen und das row_date-Objekt nach Ihren Wünschen formatieren.

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

Praneeth Nidarshan
quelle
0

Hier ist eine vordefinierte Methode, die Momentdaten oder Zeichenfolgen oder eine Mischung als Eingaben akzeptiert und eine Reihe von Daten als Momentdaten generiert. Wenn Sie keine Momentdaten als Ausgabe wünschen, ändern Sie die map()Rückgabe der Methode.

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'));
};
Kerl
quelle
0

@ softvars Lösung, aber dann einschließlich Arbeitsdatum Option

/**
 * 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;
}
koosvdkolk
quelle
0

Funktion:

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

Verwendung:

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

Hoffe es hilft dir

Nelson Dang
quelle