1

lets say I pull the min date as 1420070400000 which is 2015-01-01 00:00:00 and max date as 1575158400000 which is 2019-12-01 00:00:00.

I then try to create an array of timestamps for each month between those two dates like this:

var offset = 5*60*60000

dtMin = new Date(+1420070400000 + offset);
dtMax = new Date(+1575158400000 + offset);

console.log("dtmin: ", dtMin);
console.log("dtmax: ", dtMax);

while (dtMin <= dtMax) {

  dtRng.push((dtMin.getTime() - offset).toString());

  dtMin = new Date(new Date(dtMin).setMonth(dtMin.getMonth()+1));

}

console.log("dt rng:", JSON.stringify(dtRng));

It then returns this as the array:

["1420070400000","1422748800000","1425168000000","1427842800000","1430434800000","1433113200000","1435705200000","1438383600000","1441062000000","1443654000000","1446332400000","1448928000000","1451606400000","1454284800000","1456790400000","1459465200000","1462057200000","1464735600000","1467327600000","1470006000000","1472684400000","1475276400000","1477954800000","1480550400000","1483228800000","1485907200000","1488326400000","1491001200000","1493593200000","1496271600000","1498863600000","1501542000000","1504220400000","1506812400000","1509490800000","1512086400000","1514764800000","1517443200000","1519862400000","1522537200000","1525129200000","1527807600000","1530399600000","1533078000000","1535756400000","1538348400000","1541026800000","1543622400000","1546300800000","1548979200000","1551398400000","1554073200000","1556665200000","1559343600000","1561935600000","1564614000000","1567292400000","1569884400000","1572562800000","1575158400000"]

But sometimes it pulls back a 31 day or 30th day in there like:

Epoch date  Human readable date (GMT) 
1420070400  2015-01-01 00:00:00
1422748800  2015-02-01 00:00:00
1425168000  2015-03-01 00:00:00
1427842800  2015-03-31 23:00:00
1430434800  2015-04-30 23:00:00
1433113200  2015-05-31 23:00:00
1435705200  2015-06-30 23:00:00
1438383600  2015-07-31 23:00:00

Why is it doing that if I'm incrementing by month?

Also, my minDate and maxDate could vary...for instnace, the minDate could be 1464739200000 (Wed, 01 Jun 2016 00:00:00) and max date could be 1488326400000 (Wed, 01 Mar 2017 00:00:00)...

Also, why does it accurately do it for the first 3 months and not the ones after that then...behavior just seems weird...

---EDIT-----

trying to use momentjs for this and changed the while part to this:

   while (dtMin <= dtMax) {

       dtRng.push(dtMin);

       dtMin = moment(dtMin).add(1, 'months').toDate();
       console.log("dtmin: ", dtMin);
   }

something weird happens here...the console prints this:

Sun Feb 01 2015 00:00:00 GMT-0500 (EST)
Sun Mar 01 2015 00:00:00 GMT-0500 (EST)
Wed Apr 01 2015 00:00:00 GMT-0400 (EDT)
Fri May 01 2015 00:00:00 GMT-0400 (EDT)
Mon Jun 01 2015 00:00:00 GMT-0400 (EDT)
Wed Jul 01 2015 00:00:00 GMT-0400 (EDT)
Sat Aug 01 2015 00:00:00 GMT-0400 (EDT)
Tue Sep 01 2015 00:00:00 GMT-0400 (EDT)

but the timestamps that get pushed to dtRng look like this, notice the 30, and 31st days and 23hrs:

Epoch date  Human readable date (GMT) 
1422748800  2015-02-01 00:00:00
1425168000  2015-03-01 00:00:00
1427842800  2015-03-31 23:00:00
1430434800  2015-04-30 23:00:00
1433113200  2015-05-31 23:00:00
1435705200  2015-06-30 23:00:00
1438383600  2015-07-31 23:00:00
1441062000  2015-08-31 23:00:00
1443654000  2015-09-30 23:00:00

it should return this:

Epoch date  Human readable date (GMT) 
1422748800  2015-02-01 00:00:00
1425168000  2015-03-01 00:00:00
1427846400  2015-04-01 00:00:00
1430438400  2015-05-01 00:00:00
1433116800  2015-06-01 00:00:00
1435708800  2015-07-01 00:00:00
1438387200  2015-08-01 00:00:00
1441065600  2015-09-01 00:00:00
lightweight
  • 3,227
  • 14
  • 79
  • 142
  • Time zones, always time zones. You should consider using a library like [Moment.js](http://momentjs.com) to help with manipulating dates. See also [this question](http://stackoverflow.com/q/3674539/215552). – Heretic Monkey Dec 12 '16 at 22:49
  • @MikeMcCaughan, just tried it with momentjs but still can't seem to get it right...still getting a weird behavior... – lightweight Dec 12 '16 at 22:56
  • How are you getting those "Human readable dates"? Make sure you're using `toISOString()` or `JSON.stringify()`; otherwise it may be showing local time rather than UTC. – Heretic Monkey Dec 13 '16 at 14:24

1 Answers1

0

From the latest update, it seems like you've run into a timezone issue where you lose (or gain!?) an hour when transitioning from Eastern Standard Time (EST) to Eastern Daylight Time (EDT), which explains why you are printing 23:00:00 for some dates.

While dealing with timezones can be a bit tricky, for this particular problem, I would suggest using a simpler approach, to create all dates in UTC using the Date.UTC function. A simple loop would be to iterate through all the months for all the years:

for(var year = 2015; year < 2020; year++)
    for(var month = 0; month < 12; month++)
        dtRng.push(new Date(Date.UTC(year, month, 1, 00, 00, 00)));

The output console.log(JSON.stringify(dtRng)) seems to give the correct results:

"2015-02-01T00:00:00.000Z",
"2015-03-01T00:00:00.000Z",
"2015-04-01T00:00:00.000Z",
"2015-05-01T00:00:00.000Z",
"2015-06-01T00:00:00.000Z",
....

A modification would be to loop through start and end dates in 3 parts:

  • For the first year, loop through starting month to 12.
  • For all years except the last, loop through 1 - 12 months for each such year.
  • For the last year, loop through 1 to the last month.

Following code demonstrates this for a date range (2015/03/01 to 2019/09/01) in YYYY/MM/DD format.

// Initialize the date range.
var startYear = 2015, startMonth = 03,
      endYear = 2019,   endMonth = 09;

// Loop through the years.
for(var year = startYear; year <= endYear; year++) {
    var currStartMonth = 1, currEndMonth = 12;

    // If it's the first year, skip the months before the range.
    if (year === startYear) currStartMonth = startMonth;

    // If it's the last year, skip the months after the range.
    // Note that this also gracefully handles the case when,
    // startYear === endYear.
    if (year === endYear)     currEndMonth = endMonth;

    // Loop through the months and add it to the dates array.
    // '- 1' because of 0-indexing of month.
    for (var month = currStartMonth - 1; month < currEndMonth; month++) 
        dtRng.push(new Date(Date.UTC(year, month, 1, 00, 00, 00)));
}
John Bupit
  • 10,406
  • 8
  • 39
  • 75
  • What if my min and max timestamps can vary (sometimes they can be in the same year) but they will always show up the 1st day of the month...how can I do that without fixing the year? – lightweight Dec 12 '16 at 21:36
  • This can be easily modified to handle the same year, and/or starting with a different month. You can use the last 3 arguments in `Date.UTC` to add hours, minutes and seconds. – John Bupit Dec 12 '16 at 21:58
  • how do you loop through it though? for instance, if my min date is 1464739200000 (`Wed, 01 Jun 2016 00:00:00`) and my max date is 1488326400000 (`Wed, 01 Mar 2017 00:00:00`), how would I create the months between those two? – lightweight Dec 12 '16 at 22:20
  • here is another question too, my original way, how can it accurately increment one month for the first 3 and then not do it for the next ones? – lightweight Dec 12 '16 at 22:33