2

I have an something like this

{
    1489330777089: 100, // 12 March
    1489330824346: 45,  // 12 March
    1489330877089: 90,  // 13 March
    1489330824346: 120, // 13 March
    .....
}

the key is from Date.now() as they are created, and the value is an integer.

I want to plot these data into charts, like a bar graph with Dates as x-axis.

How do I use Javascript to group these data into dates, with the integer value summed up together. Expected result to be:

{
    12 March 2017: 145 // 100 + 45
    13 March 2017: 210 // 90 + 120
    ...
} 

(I'm using this inside React app, if that's important to note. Also, using Firebase to store data)

Thanks!

Gaddafi Rusli
  • 320
  • 4
  • 19
  • You can get the `Date` with `var date = new Date(milliseconds);`. With `date.toString()` you get a readable date-string. Just put it into a loop and your done. – Schokokuchen Bäcker Mar 12 '17 at 15:32
  • @SchokokuchenBäcker Sorry, I updated the question to make it clearer. I don't only want to convert the milliseconds to date, I also want to group those with the same dates into one. With integer value being summed up as well – Gaddafi Rusli Mar 12 '17 at 15:37
  • Note that due to time zone effects, these time values may represent different dates in different timezones. For me, all 4 time values are on 13 March. Do you want to compare them in a particular timezone? This is very similar to [*get date string from utc unixtime and add a timezone offset*](http://stackoverflow.com/questions/42722400/get-date-string-from-utc-unixtime-and-add-a-timezone-offset). – RobG Mar 12 '17 at 20:26
  • Your object literal is invalid, there are two "1489330824346" properties so the value 45 is overwritten by 90. – RobG Mar 13 '17 at 00:37
  • @RobG Yep, my sample data up there is not actually real millisecond that correspond to those dates. I just wanted to illustrate my question better. Sorry if that's misleading – Gaddafi Rusli Mar 13 '17 at 00:40

3 Answers3

0

This goes through the values, truncates them up to day, and makes the output with the sum of the grouped values

let source = {
    1489330777089: 100,
    1489330824346: 45, 
    1489330877089: 90, 
    1489330824346: 120,
}

let grouped = Object.keys(source).reduce((output, key) => {
  let date = new Date(Number(key)),
      groupedDate = new Date(date.getFullYear(), date.getMonth(), date.getDay());

  if (typeof output[groupedDate] === 'undefined') output[groupedDate] = 0;

  output[groupedDate] += source[key];

  return output;
}, {});

You might want to change the output property string / the operator / the truncate unit but this should be easy by small changes in the code above.

smnbbrv
  • 23,502
  • 9
  • 78
  • 109
  • Thanks! This is great. Any advantage of using your method compared to the one provided by Nina Scholz here? – Gaddafi Rusli Mar 13 '17 at 00:12
  • This does not allow for time zones. All of these time values are on the same date, so for me, the result is `{ Wed Mar 01 2017 00:00:00 GMT+1000: 310 }`. – RobG Mar 13 '17 at 00:28
  • @RobG I wouldn't worry about timezone for now. Plus, my sample data up there is not actually real millisecond that correspond to those dates. But you're right. I also would like to know in terms of performance comparison :) – Gaddafi Rusli Mar 13 '17 at 00:39
  • @GaddafiRusli—but you have to worry about timezone, since that will determine the date that the values are perceived to represent. Viewed in UTC, they are all on 12 March. In my timezone, they are all 13 March. So you will get different results based on the timezone setting of the host on which the code is executed. Performance is irrelevant if the solution doesn't give correct results. And using *let* for global variables doesn't make much sense either, it greatly restricts compatibility for no benefit. – RobG Mar 13 '17 at 01:13
0

You could use the ISO date for grouping. Maybe you need to use an ofsett for the right local time.

var data = { 1489330777089: 100, 1489330824346: 45, 1489330877089: 90, 1489330824346: 120 },
    grouped = {};

Object.keys(data).forEach(function (k) {
    var date = (new Date(+k +1000*60*60*24)).toISOString().slice(0, 10);
    grouped[date] = grouped[date] || 0;
    grouped[date] += data[k];
});

console.log(grouped);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You can do like this

var date_obj={
    1489330777089: 100, // 12 March
    1489330824346: 45,  // 12 March
    1489330877089: 90
 }
 var tempData = {};
for ( var index in date_obj ) {
  if ( date_obj[index] != "undefined" ) { 
      var milisec=  parseInt(index);
      var get_data= new Date(milisec);
var str_date=get_data.toString();
  var date_str=  str_date.substr(0,15);
  if(typeof(tempData[date_str])=== "undefined"){
    tempData[date_str] = parseInt(date_obj[index]); 
  }else{
      tempData[date_str] = tempData[date_str]+parseInt(date_obj[index]); 
  }
  } 
 }
data = tempData;
console.log(data);
dpkrai96
  • 93
  • 1
  • 11