1

I have an array consisting of time durations like ['00:30', '01:30', '03:00', '04:30'] and I am trying to add the array elements to get total time duration. I am trying the below code to do this job but I am getting a irrelevant output like 00000.5010.503040.5:0. Have anyone tried this kind of sum earlier?

function calc_tot_dur() {
  var total_durs = ['00:30', '01:30', '03:00', '04:30'];
  var dim = '00:00';
  jQuery.each(total_durs, function(index, value) {
    //console.log(value);
    dim_split = dim.split(":");
    hs = dim_split[0];
    ms = dim_split[1];

    value_split = value.split(":");
    v_hs = value_split[0];
    v_ms = value_split[1];
    console.log(hs + v_hs);
    dim = (hs + v_hs) + ':' + (ms + v_ms);
    // console.log(dim);
    ms_hs = (ms + v_ms) / 60;
    if (ms_hs > 0) {
      dim = (hs + v_hs + ms_hs) + ':' + (00);
    } else {
      dim = (hs + v_hs) + ':' + (ms + v_ms);
    }
  });
  alert(dim);
}
3
  • 3
    you are adding strings, not numbers Commented Apr 25, 2016 at 10:53
  • yes, and on top of that, you are splliting AND modifying the dim variable for every iteration of the loop. Commented Apr 25, 2016 at 10:56
  • adding strings leads to concatenating them. You need to be converting them to numbers to add them Commented Apr 25, 2016 at 10:58

5 Answers 5

2

A solution with reduce and a correction for the length of the parts.

var total_durs = ['00:30', '01:30', '03:00', '04:30'],        
    result = function (array) {
        var total = array.reduce(function (r, a) {
                var aa = a.split(':').map(Number);
                return r + 60 * aa[0] + aa[1];
            }, 0);
			
        return [Math.floor(total / 60), total % 60].map(function (a) {
            var s = a.toString();
            return s.length < 2 ? '0' + s : s;
        }).join(':');
    }(total_durs);

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Sign up to request clarification or add additional context in comments.

1 Comment

thumbs up for correction for the length of the parts
1

You only miss some parseInt in some places so when you sum

"00" + "00" //as string it become 0000
parseInt("00") + parseInt("00") //will become 0

so the change:

function calc_tot_dur() {
  var total_durs = ['00:30', '01:30', '03:00', '04:30'];
  var dim = '00:00';
  jQuery.each(total_durs, function(index, value) {      
    dim_split = dim.split(":");
    hs = parseInt(dim_split[0]);   // here
    ms = parseInt(dim_split[1]);   // here   

    value_split = value.split(":");
    v_hs = parseInt(value_split[0]);   // here
    v_ms = parseInt(value_split[1]);   // here
    dim = (hs + v_hs) + ':' + (ms + v_ms);

    ms_hs = parseInt((ms + v_ms) / 60);   // here
    if (ms_hs > 0) {
      dim = (hs + v_hs + ms_hs) + ':' + (00);
    } else {
      dim = (hs + v_hs) + ':' + (ms + v_ms);
    }
 });
 console.log(dim);
}

Comments

1

You could try using Moment, which is a great library for handling dates and durations in javascript. Here is a fiddle showing it in action:

https://jsfiddle.net/25zfe4h1/

function calc_tot_dur() {
  var total_durs = ['00:30', '01:30', '03:00', '04:30'];
  var dim = '00:00';
  jQuery.each(total_durs, function(index, value) {
    var duration = moment.duration(value);
    dim = moment.duration(dim).add(duration);
  });
  alert(formatResult(dim));
}

function formatResult(res) {
  return res.hours() + ':' + res.minutes();
  // return res.humanize();
}

calc_tot_dur();

Notice how much less you have to write? It also has the benefit that you can humanize the output, so instead of '00:30' it would say '30 minutes'.

Comments

1

you need to convert to number before adding

var total_durs = ['00:30', '01:30', '03:00', '04:30'];
var total = 0;
total_durs.forEach(function(val){
  var times = val.split(":");
  var num = parseInt(times[0],10) + parseInt(times[1],10)/60;
  total += num;
});

Now convert total to the time format (hh:mm)

var numstring = String(total).split(".");
var display = ("0" + String(numstring[0])).slice(-2) + ":" + String(numstring[1]*6);

DEMO

    var total_durs = ['00:30', '01:30', '03:00', '04:30'];
    var total = 0;
    total_durs.forEach(function(val){
      var times = val.split(":");
      var num = parseInt(times[0],10) + parseInt(times[1],10)/60;
      total += num;
    });


    var numstring = String(total).split(".");
    var display = ("0" + String(numstring[0])).slice(-2) + ":" + String(numstring[1]*6);

alert(display);

Comments

1

A simple one liner functional solution could be

var arr = ['00:30', '01:30', '03:00', '04:30'],
    tot = arr.map(e => e.split(":").map(e => e*1)).reduce((p,c) => [p[0] + c[0] + ~~((p[1]+c[1])/60), (p[1]+c[1])%60]);

document.write("<pre>" + tot[0] + ":" + tot[1] + "</pre>");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.