Running Turtle Running Turtle - 5 months ago 28
Node.js Question

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

In a nodejs application, I have an array of event objects formatted as follows:

eventsArray = [ {id: 1, date: 1387271989749 }, {id:2, date: 1387271989760}, ... ]


eventsArray having a variable length of n elements, and supposing I choose time reference to be Paris time, I want to be able to group elements by day, week, or month:

groupedByDay = {

2012: { ... },
2013: {
dayN : [{id: a0, date: b0}, {id: a1, date: b1}, {id: a2, date: b2 }],
dayN+1: [{id: a3, date: b3}, {id: a4, date: b4}, {id: a5, date: b5 }],
...
},
2014: { ... }

}

groupedByWeek = {
2012: { ... }
2013: {
weekN: [{id: a0, date: b0}, {id: a1, date: b1}, {id: a2, date: b2 }],
weekN+1: [{id: a3, date: b3}],
....
},
2014: { ... }
}

groupedByMonth = {
2012: { ... },
2013: {
monthN: [ {id: a0, date: b0 }, {id: a1, b1}, {id: a2, b2}, {id: a3, b3 }],
monthN+1: [ {id: a4, date: b4 }, {id: a5, b5}, {id: a6, b6}],
...
},
2014: { ... }
}


Having very little experience with manipulating unix timestamps, I was wondering how this could be done or if there was an npm module that would make this easier.

Answer

Something like this is probably close to what you need.

Javascript Date has getFullYear, getDate and getMonth functions (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) and you can also check out this SO post (Convert a Unix timestamp to time in Javascript).

The basic method here (arrange) builds up the hashes by year, and then by day and month.

This code doesn't do week. Do you mean which week of the year or which month? I suspect you could write your own date method to grab that number and then follow the pattern below to grab all the data you want. You can get the day of the week from JS (getDay). I'm not sure how you want to compute week, but that method might help out.

I ran this code in a browser (after initializing a dummy set of eventsArray) but I suspect it'd translate to node just fine.

You should properly namespace the function and you could move all the methods into the object prototype, if you were so inclined.

Hope this helps

var groupEvents = function(eventsArray) {

  this.dates = eventsArray;

  this.arranged = {};

  this.monthKey = function(month) {
    return 'month' + month;
  };
  this.dayKey = function(month) {
    return 'day' + month;
  };
  this.getYear = function(year) {
    this.arranged[year] = this.arranged[year] || {}
    return this.arranged[year]
  };
  this.getMonth = function(month, year) {
    var y = this.getYear(year);
    var k = this.monthKey(month);
    y[k] = y[k] || [];
    return y[k]
  };
  this.getDate = function(day, year) {
    var y = this.getYear(year);
    var k = this.dayKey(day);
    y[k] = y[k] || [];
    return y[k]
  };
  this.addToMonth = function(info, month, year) {
    var y = this.getMonth(month,year);
    y.push(info);
  };
  this.addToDay = function(info, day, year) {
    var y = this.getDate(day,year);
    y.push(info);
  };
  this.breakdownDate = function(date) {
    return {
      month: date.getMonth(),
      day: date.getDate(),
      year: date.getFullYear()
    };
  }
  /** grab a date, break it up into day, month year
      and then categorize it */
  this.arrange = function() {
    if(!this.arranged.length) {
      var ii = 0;
      var nn = this.dates.length;
      for(; ii < nn; ++ii ) {
        var el = this.dates[ii];
        var date = new Date(el.date * 1000);
        var parsed = this.breakdownDate(date);
        this.addToMonth(el, parsed.month, parsed.year);
        this.addToDay(el, parsed.month, parsed.year);
      }
    }
    return this.arranged;
  };
  return this;
};

if(eventArray.length) {
  var events = new groupEvents(eventArray);
  var arranged = events.arrange();
  console.log(arranged);
}