Date Range is starting with Plus

Viewed 50

I have created a small function which give all dates between two dates.

but this is starting from Plus 1 date.

Here's my code (also on Here is jsfiddle):

function DateRangeArr(to, from) {
    console.log(to);
    console.log(from);
    var Dateresult = [];

    var end = new Date(from);
    var loop = new Date(to);

    while (loop <= end) {
        Dateresult.push({ 'total': 0, 'log_date': loop });
        var newDate = loop.setDate(loop.getUTCDate() + 1);
        loop = new Date(newDate);
    }
    return Dateresult;
}

console.log(DateRangeArr('2020-12-05','2020-12-12'));

It's giving me results starting from 2020-12-06 to 2020-12-13. Also will it gives result depending upon user time zone ?

1 Answers

There are a couple of things going on that could account for the problem.

  • (This is probably the thing you're seeing) You're changing the state of the Date instance that you added to the array after adding it. That changes the instance that's in the array.
  • Since "2020-12-05" is a date-only string, it's parsed as UTC in specification-compliant browsers (see the rules at Date.parse), so the Date objects will represent midnight on that date UTC rather than midnight on that date in your local timezone. If you want them to reliably be midnight local time, add T00:00 to the string. If you want them to be parsed reliably as UTC, you should be able to use them as-is, but the spec moved around on this (ES2015 said they should be parsed as local time, not UTC, before being updated by ES2016) so to get UTC reliably, add T00:00Z to it. (My understanding is that the spec allows just adding a Z, but others read the spec differently, and both Safari's JavaScriptCore and Firefox's SpiderMonkey reject new Date("2020-12-05Z"), so add T00:00Z.) Or use new Date(Date.UTC(year, month - 1, day)) instead.
  • You're mixing up accessors here: loop.setDate(loop.getUTCDate() + 1). That's using the UTC accessor to get the date, but then the local time accessor to set it. You need to be consistent in order to add a day to the date.
  • You haven't said how you're using the resulting array of Date objects, but just note that the date they show may seem off if (for instance) you parse them as UTC but then display the result in local time or vice-versa, because of the time zone offset.
  • You have to and from reversed in your code. You're using them consistently, but it's quite hard to read. :-) When building an array in date order, it goes from the earlier date to the later date.

Here's a version updated to work entirely in UTC; the resulting Date objects represent midnight UTC on each of the dates:

function dateRangeArr(from, to) {
    console.log(from);
    console.log(to);
    var dates = [];

    var end = new Date(to + "T00:00Z");
    var loop = new Date(from + "T00:00Z");

    while (loop <= end) {
        dates.push({ "total": 0, "log_date": new Date(+loop) });
        loop.setUTCDate(loop.getUTCDate() + 1);
    }
    return dates;
}

console.log(dateRangeArr("2020-12-05","2020-12-12"));

(I've also updated the function and variable names to be more consistent with standard practice in JavaScript, since the function isn't a constructor function.)

Here's a version that works in local time instead:

function dateRangeArr(from, to) {
    console.log(from);
    console.log(to);
    var dates = [];

    var end = new Date(to + "T00:00");
    var loop = new Date(from + "T00:00");

    while (loop <= end) {
        dates.push({ "total": 0, "log_date": new Date(+loop) });
        loop.setDate(loop.getDate() + 1);
    }
    return dates;
}

console.log(dateRangeArr("2020-12-05","2020-12-12"));

Which you use depends on whether you want the Date instances to represent midnight UTC (use the UTC version) or midnight local time (use the local time version).

Related