nicole willson
nicole willson

Reputation: 29

Calculating Average from HH:mm in JS

i have the following array which includes hh:mm

var times= [ '28:06', '27:56', '28:30']

im trying to calculate the average hours and min from the above array

bellow is my code

var times= [ '28:06', '27:56', '28:30'],
date = 0,
result = '';
function offsetify(t){
return t < 10 ? '0' + t : t;
}
for(var x = 0; x < times.length; x++ ) {
var tarr = times[x].split(':');
date += new Date(0, 0, 0, tarr[0], tarr[1]).getTime();   
}
var avg = new Date(date/times.length);
result = offsetify(avg.getHours()) + ':' + offsetify(avg.getMinutes());
console.log(result);

which gives me 4:10 which is wrong as the average should be somewhere around 27: ...

what im doing wrong here

Upvotes: 1

Views: 142

Answers (4)

Coding Edgar
Coding Edgar

Reputation: 1465

When transforming >24h to day, you elapsed a day, when you do the average, the average is algo >24h, therefor also elapsing a day.

check avg.getDay() to do the right offset with the hour.

var times= [ '28:06', '27:56', '28:30'],
date = 0,
result = '';
function offsetify(t){
return t < 10 ? '0' + t : t;
}
for(var x = 0; x < times.length; x++ ) {
var tarr = times[x].split(':');
date += new Date(0, 0, 0, tarr[0], tarr[1]).getTime();   
}
var avg = new Date(date/times.length);
result = offsetify((avg.getDay() * 24) + avg.getHours()) + ':' + offsetify(avg.getMinutes());
console.log(result);

Note: I'll also recommend you using https://momentjs.com/docs/#/durations/ if there's much time calc involved in your project.

Upvotes: 1

Ranjit Singh
Ranjit Singh

Reputation: 3735

You can simply find the average of hour and minute part separately

var times= [ '28:06', '27:56', '28:30']

function getAverage(isHourPart){
	var sum = 0;
	times.forEach(function(value){
  	sum+=parseInt(value.split(':')[isHourPart?0:1], 10);
  });
  var avg = Math.floor(sum/times.length);
  return avg<10 ? '0' + avg : avg;
}

console.log(getAverage(true)+":"+getAverage(false));

But if you consider combined value of hour and minute

var times= [ '28:06', '27:56', '28:30']

function getSum(){
	var sum = 0;
	times.forEach(function(value){
  	var item = value.split(':');
  	sum+=parseInt(item[0], 10) * 60 + parseInt(item[1], 10);
  });
  return sum;
}

function getFormattedText(value){
	return value<10?"0"+value:value;
}

var totalMinutes = getSum()/3;

var hour = Math.floor(totalMinutes/60);
var minute = Math.floor(totalMinutes - hour * 60);

console.log(getFormattedText(hour)+":"+getFormattedText(minute));

Upvotes: 2

Subhasish Biswasray
Subhasish Biswasray

Reputation: 28

var times= [ '28:06', '27:56', '28:30'];

var total=0;
for(var i=0;i<times.length;i++) {
    var hour=parseInt(times[i].split(':')[0]);
    var minute=parseInt(times[i].split(':')[1]);
    total+=((hour*60)+minute);
}
var avg=parseInt(total/times.length);
var result=parseInt(avg/60)+":"+(avg%60);
console.log(result);

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370929

I'd use .map to transform each time string into a minutes count (eg 28:06 -> (28 * 60) + 6 = 1686), then sum up the array and divide by its length. Once you have the average number of seconds, you can turn the process around to create another HH:mm string:

var times = ['28:06', '27:56', '28:30'];
const timeMins = times.map((str) => {
  const [hours, minutes] = str.split(':').map(Number);
  return minutes + (hours * 60);
});
const totalMins = timeMins.reduce((a, b) => a + b);
const avgMins = totalMins / times.length;
const hours = Math.floor(avgMins / 60);
const minutes = avgMins % 60;
console.log(hours + ':' + Math.round(minutes));

Upvotes: 2

Related Questions