Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate a full array of date objects

The Problem

I'm using nvd3 to render some date-specific data. However, if there was no data for a particular date, no record exists for it, and nvd3 does not render that data point, instead interpolating between the data points that do exist. I therefore need to generate the missing dates so that nvd3 displays dates which had no data associated with them.

What I want to do

I need to generate an array that looks like this:

[ {year: 2015, month: 1, day: 1},
  {year: 2015, month: 1, day: 2},
  ...
]

The function generating this array will take a starting date and an ending date, and generate all days between those two dates.

I will then merge it with my data array. That way dates that have data will have data, and dates that don't have data will still show up on the graph, without skipping over any missing dates.

Is there an easy way to do this with the Date object? I.e. when generating this array I need to know which months have 30 or 31 days, that February is special, leap years, etc, etc... I could brute-force it by specifying the number of days for each month, but I'd like to know if there's any easier way to do this.

like image 526
sg.cc Avatar asked Dec 07 '25 00:12

sg.cc


2 Answers

Try this:

function getDateArray(startDate, days){
   return Array(days)
            .fill()
            .map(function(e,idx) { 
                var d = new Date(startDate); 
                d.setDate(d.getDate() + idx); 
                return {
                    year: d.getFullYear(), 
                    month: d.getMonth() + 1, 
                    day: d.getDate() }; 
                }
             );
}
like image 85
Malk Avatar answered Dec 09 '25 13:12

Malk


You don't neccessarily need to know the number of days in a particular month.

var date = new Date(2016, 0, 31);
console.log(date); // Sun Jan 31 2016 00:00:00 GMT-0600 (Central Standard Time)
date.setDate(date.getDate() + 1);
console.log(date); // Mon Feb 01 2016 00:00:00 GMT-0600 (Central Standard Time)

You could iterate a Date until you want to get to the end point.

See this question: Incrementing a date in JavaScript


Edit

I felt bad that I didn't include an implementation, so here is my way, which is slightly similar to Malk's answer except it uses String.repeat() instead of the Array constructor which keeps jslint from complaining and returns a Date object instead of an Object literal. String.repeat() isn't supported by IE either.

/*jslint node:true*/

"use strict";

/*
 * Function to fill a series of dates
 * @param {Date} start The staring date
 * @param {Number} n The number of days to fill out
 * @returns {Date[]} The Date objects of the series
 */
function fillDateSeries(start, n) {
    return "#".repeat(n).split("").map(function (e, i) {
        var date = new Date();
        date.setDate(start.getDate() + i);
        return date;
    });
}

// Usage
console.log(fillDateSeries(new Date(), 5));

Prints:

[ Mon Feb 01 2016 18:24:29 GMT-0600 (Central Standard Time),
  Tue Feb 02 2016 18:24:29 GMT-0600 (Central Standard Time),
  Wed Feb 03 2016 18:24:29 GMT-0600 (Central Standard Time),
  Thu Feb 04 2016 18:24:29 GMT-0600 (Central Standard Time),
  Fri Feb 05 2016 18:24:29 GMT-0600 (Central Standard Time) ]
like image 42
zero298 Avatar answered Dec 09 '25 13:12

zero298



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!