How to group objects with timestamps properties by day, week, month?

All the solutions above are hefty, pure JS, vanilla solutions. If you're okay to use a couple of libraries, then lodash and moment can be used together for a simple one liner:

ES6

let groupedResults = _.groupBy(results, (result) => moment(result['Date'], 'DD/MM/YYYY').startOf('isoWeek'));

Older JS

var groupedResults = _.groupBy(results, function (result) {
  return moment(result['Date'], 'DD/MM/YYYY').startOf('isoWeek');
});

This will result in an array that's keyed by the start of the week, such Mon Jul 25 2016 00:00:00 GMT+0100. I'm sure you can work out how to expand on it to get months, years, etc.

RE: @SaintScott's comments

It was mentioned in the comments that this doesn't directly answer the question because the original uses UTC timestamps rather than formatted dates. In this case, you should use moment() without the second parameter:

moment(1387271989749).startOf('isoWeek');

Or if using a UNIX timestamp, as follows:

moment.unix(yourTimestamp).startOf('isoWeek');

... although this is starting to get further from the question and more into the Moment documentation, which I'd advise reading if you want to use this method.


I would do something like this :

var item,
    i = 0,
    groups = {},
    year, day;
while (item = eventsArray[i++]) {
    item = new Date(item.date);
    year = item.getFullYear();
    day = item.getDate();
    groups[year] || (groups[year] = {}); // exists OR create {}
    groups[year][day] || (groups[year][day] = []);  // exists OR create []
    groups[year][day].push(item);
}

This version groups items by days only, but you can easily get the same result for weeks and months replacing item.getDate() with the appropriate function :

  • getWeek() : https://stackoverflow.com/a/6117889/1636522.
  • getMonth() : MDN doc (zero based!).

Expanding on @user568109's answer, which is correct and up-voted, here's one function that does it all, with a bigger array for demonstration's sake:

// Group by time period - By 'day' | 'week' | 'month' | 'year'
// ------------------------------------------------------------
var groupByTimePeriod = function (obj, timestamp, period) {
  var objPeriod = {};
  var oneDay = 24 * 60 * 60 * 1000; // hours * minutes * seconds * milliseconds
  for (var i = 0; i < obj.length; i++) {
    var d = new Date(obj[i][timestamp] * 1000);
    if (period == 'day') {
      d = Math.floor(d.getTime() / oneDay);
    } else if (period == 'week') {
      d = Math.floor(d.getTime() / (oneDay * 7));
    } else if (period == 'month') {
      d = (d.getFullYear() - 1970) * 12 + d.getMonth();
    } else if (period == 'year') {
      d = d.getFullYear();
    } else {
      console.log('groupByTimePeriod: You have to set a period! day | week | month | year');
    }
    // define object key
    objPeriod[d] = objPeriod[d] || [];
    objPeriod[d].push(obj[i]);
  }
  return objPeriod;
};

var eventsArray = [{ id: 1, date: 1317906596 }, { id: 2, date: 1317908605 }, { id: 3, date: 1317909229 }, { id: 4, date: 1317909478 }, { id: 5, date: 1317909832 }, { id: 6, date: 1317979141 }, { id: 7, date: 1317979232 }, { id: 8, date: 1317986965 }, { id: 9, date: 1318582119 }, { id: 10, date: 1318595862 }, { id: 11, date: 1318849982 }, { id: 12, date: 1318855706 }, { id: 13, date: 1318929018 }, { id: 14, date: 1318933265 }, { id: 15, date: 1318940511 }, { id: 16, date: 1318945096 }, { id: 17, date: 1319017541 }, { id: 18, date: 1319527136 }, { id: 19, date: 1318582119 }, { id: 20, date: 1318595862 }, { id: 21, date: 1318582119 }, { id: 22, date: 1318595862 }, { id: 23, date: 1319713399 }, { id: 24, date: 1320053428 }, { id: 25, date: 1320333481 }, { id: 26, date: 1320832755 }, { id: 27, date: 1321012378 }, { id: 28, date: 1321280993 }, { id: 29, date: 1321347659 }, { id: 30, date: 1321350476 }, { id: 31, date: 1321369307 }, { id: 32, date: 1321369614 }, { id: 33, date: 1321610123 }, { id: 34, date: 1321613205 }, { id: 35, date: 1321617250 }, { id: 36, date: 1321626603 }, { id: 37, date: 1321865808 }, { id: 38, date: 1321876609 }, { id: 39, date: 1321877598 }, { id: 40, date: 1321877832 }, { id: 41, date: 1321953322 }, { id: 42, date: 1322061969 }, { id: 43, date: 1322142603 }, { id: 44, date: 1322211686 }, { id: 45, date: 1322213793 }, { id: 46, date: 1322214569 }, { id: 47, date: 1322482817 }, { id: 48, date: 1322663742 }, { id: 49, date: 1322664267 }, { id: 50, date: 1322747231 }, { id: 51, date: 1322819964 }, { id: 52, date: 1323358224 }, { id: 53, date: 1323681272 }, { id: 54, date: 1323695093 }, { id: 55, date: 1323696589 }, { id: 56, date: 1323763763 }, { id: 57, date: 1322819964 }, { id: 58, date: 1323681272 }, { id: 59, date: 1323851164 }, { id: 60, date: 1323853123 }, { id: 61, date: 1323854271 }, { id: 62, date: 1323858072 }, { id: 63, date: 1325690573 }, { id: 64, date: 1325751893 }, { id: 65, date: 1325760204 }, { id: 66, date: 1325769098 }, { id: 67, date: 1325769981 }, { id: 68, date: 1325771632 }, { id: 69, date: 1325776473 }, { id: 70, date: 1325837346 }, { id: 71, date: 1326110199 }, { id: 72, date: 1326793097 }, { id: 73, date: 1326878182 }, { id: 74, date: 1326881341 }, { id: 75, date: 1326975873 }, { id: 76, date: 1326985667 }, { id: 77, date: 1327047585 }, { id: 78, date: 1327062945 }, { id: 79, date: 1327063660 }, { id: 80, date: 1327322844 }, { id: 81, date: 1327326904 }, { id: 82, date: 1327329215 }, { id: 83, date: 1327397042 }, { id: 84, date: 1327399839 }, { id: 85, date: 1327401818 }, { id: 86, date: 1327407161 }, { id: 87, date: 1327419420 }, { id: 88, date: 1327570243 }, { id: 89, date: 1327578536 }, { id: 90, date: 1327584554 }, { id: 91, date: 1327914616 }, { id: 92, date: 1327917019 }, { id: 93, date: 1327931685 }, { id: 94, date: 1327933025 }, { id: 95, date: 1327934772 }, { id: 96, date: 1327947074 }, { id: 97, date: 1328626734 }, { id: 98, date: 1328626734 }, { id: 99, date: 1330070074 }, { id: 100, date: 1330073135 }, { id: 101, date: 1330073259 }, { id: 102, date: 1330332445 }, { id: 103, date: 1330351925 }, { id: 104, date: 1330420928 }, { id: 105, date: 1330423209 }, { id: 106, date: 1330437337 }, { id: 107, date: 1330439446 }];

var objPeriodDay = groupByTimePeriod(eventsArray, 'date', 'day');
var objPeriodWeek = groupByTimePeriod(eventsArray, 'date', 'week');
var objPeriodMonth = groupByTimePeriod(eventsArray, 'date', 'month');
var objPeriodYear = groupByTimePeriod(eventsArray, 'date', 'year');

console.log(objPeriodDay);
console.log(objPeriodWeek);
console.log(objPeriodMonth);
console.log(objPeriodYear);

And here's a fiddle to go with it (you will have to open the console to see the output).

As you'll see in the fiddle, the keys for the 4 objects will be as follows:

  • objPeriodDay: the day number since 1st Jan 1970
  • objPeriodWeek: the week number relative to the first week of 1st Jan 1970
  • objPeriodMonth: the month number since 1st Jan 1970
  • objPeriodYear: the year

Note that all these four variations will give you unique keys. Month, for instance, will give you "Dec 2011" (in the form of months since 1st Jan 1970), not just "Dec".


Here is my solution. Keep in mind that day, week and month are relative to origin, since epoch:

let event = [ {id: 1, date: 1387271989749 }, {id:2, date: 1387271989760} ];

function groupday(value, index, array){
   let byday={};
    let d = new Date(value['date']);
    d = Math.floor(d.getTime()/(1000*60*60*24));
    byday[d]=byday[d]||[];
    byday[d].push(value);
  return byday
}

function groupweek(value, index, array){
  let byweek={};
   let d = new Date(value['date']);
    d = Math.floor(d.getTime()/(1000*60*60*24*7));
    byweek[d]=byweek[d]||[];
    byweek[d].push(value);
  return byweek
}

function groupmonth(value, index, array){
   let bymonth={};
    d = new Date(value['date']);
    d = (d.getFullYear()-1970)*12 + d.getMonth();
    bymonth[d]=bymonth[d]||[];
    bymonth[d].push(value);
  return bymonth
}

console.log('grouped by day', event.map(groupday));
console.log('grouped by week',event.map(groupweek));
console.log('grouped by month',event.map(groupmonth));


NOTE: Objects are grouped but the keys for day, week and month are in digits. Only the key for year is human readable.