简体   繁体   中英

How to group timelines by hrs

Lets say I have array of JSON data with timeStarted and timeEnded values in Date format. I am struggling to group timeSpent by hours. For example,

[{timeStarted: '00:10:30', timeEnded: '00:14:02'}, 
{timeStarted: '00:48:08', timeEnded: '02:33:33'}, ...]

I am trying to group them so I get array like

[{hrs: '0', timeSpent: '16'}, 
{hrs: '1', timeSpent: '60'}, 
{hrs: '2', timeSpent: '34'}, ...]

I have tried like billion times to group them but I cant figure out how: I always get values like 95 mins in hour. At least I need a right way to think. Thanks.

Based on the values you have for timeSpent and your first array, it sounds like you want to get an array representing how much of each clock hour (eg from 9:00 to 10:00 or 14:00 to 15:00) was "spent" .

If that's so, you can do this by getting the hours and minutes (or even seconds, if you want to go that granular) of each interval and tallying up how many minutes have been added to each individual hour.

For a simple case where the interval is within a single clock hour, you can do this by subtracting the end time from the start time. In a multi-hour interval it's a little more complicated. See the code below for one way you could handle this. There are probably better ways, and the code only goes down to the minute, but it's a start.

The keys of the hours array below correspond to each clock hour.

const timesElapsed = [
  {timeStarted: '00:10:30', timeEnded: '00:14:02'}, 
  {timeStarted: '00:48:08', timeEnded: '02:33:33'}
]

// Initialize hours array: each key of the array represents a specific clock hour
let hours = []
for (let interval of timesElapsed) {
  // Get the pertinent data as Numbers
  const startHour = (Number)(interval.timeStarted.split(':')[0])
  const startMinute = (Number)(interval.timeStarted.split(':')[1])
  const endHour = (Number)(interval.timeEnded.split(':')[0])
  const endMinute = (Number)(interval.timeEnded.split(':')[1])

  // Initialize elements in Hour array if need be
  if (hours[startHour] === undefined) hours[startHour] = 0
  if (hours[endHour] === undefined) hours[endHour] = 0

  // An interval within an hour
  if (startHour === endHour) {
    hours[startHour] += (endMinute - startMinute)
  } else {
    // The first hour of a multi-hour interval
    hours[startHour] += 60 - startMinute

    // The middle hours, if any
    for (let i = startHour + 1; i < endHour; i++)
      hours[i] = 60

    // The final hour
    hours[endHour] += endMinute
  }
}

// console.log(hours)
// [16, 60, 33]

If your times are always strings in the format hh:mm:ss , then a simple string split with some math could work:

const times = [
  { timeStarted: '00:10:30', timeEnded: '00:14:02' }, 
  { timeStarted: '00:48:08', timeEnded: '02:33:33' },
];
const withHours = times.map(time => {
  // Split on colon to get the components of the timestamp
  var start = time.timeStarted.split(':');
  var end = time.timeEnded.split(':');

  // Convert to seconds by multiplying each component by how many seconds it's worth
  var startSeconds = (+start[0]) * 60 * 60 + (+start[1]) * 60 + (+start[2]);
  var endSeconds = (+end[0]) * 60 * 60 + (+end[1]) * 60 + (+end[2]);

  // Find the difference in seconds and convert back to hours
  // We'll also floor this cause it looks like you want ints rounded down
  var hrs = Math.floor((endSeconds - startSeconds) / (60 * 60));

  return {
    timeStarted: time.timeStarted,
    timeEnded: time.timeEnded,
    hrs,
  };
});

EDIT

Just noticed you have an additional field there called timeSpent . Not sure what that is supposed to be.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM