1

I am using DataTables to collect duration spent fundraising for each person and then display their share of the funds raised to go towards a camp.

I am trying to add duration together using moment (the duration can be greater than 24 hours). I then want to get the fraction for each and times by the dollar amount raised to work out the amount to disperse to each person. For instance total calculated duration spent is 10 hours and total raised is $100.00, James spent 2:30 which is 0.25 of 10 hours so will receive $25.00 towards the camp.

My calculation of total hours only returns the last duration entered (e.g, if I enter 1:30 and 3:00 then totalHours returned is 3:00).

How do I correctly add the duration? How do I divide each duration into totalHours to get the correct fraction? How do I then write the calculated disbursement to column 7 for each person?

My code is:

    var totalHours;
    // this gets each node (cell) in the final column:
    memDispTable.columns(5).nodes().to$()[0].forEach(function (item) {
        // see if the display value is a number (i.e. not blank):
        var hours = $('input', item ).val();
        console.log("hours: " + hours);
        if (moment(hours, "HH:mm").isValid()) {
            totalHours = moment.duration(moment.utc(totalHours,'HH:mm')).add(moment.duration(hours, 'HH:mm'));
            totalHours = moment.utc(totalHours.as('milliseconds')).format("HH:mm");
            console.log("totalHours: " + totalHours);
        }
    });
    $('#showDispHours').val(totalHours);

@AlwaysHelping provided this solution, except it does not go past 24 hours:

var totalHours = 0;
    // this gets each node (cell) in the final column:
    memDispTable.columns(5).nodes().to$()[0].forEach(function (item) {
        // see if the display value is a number (i.e. not blank):
        var hours = $('input', item ).val();
        console.log("hours: " + hours);
        if (moment(hours, "HH:mm").isValid()) {
            
            var start = moment(hours, "HH:mm");
            var diff = start.diff(start.clone().startOf('day'));
            totalHours += diff;
            console.log("totalHours: " + totalHours);
            
        }
    });
    
    var duration = moment.duration(totalHours); //get total
    $("#showDispHours").text(duration.hours() + ':' + duration.minutes());

In addition to the excellent answer provided by @AlwaydHelping the final piece is from:

How to convert time milliseconds to hours, min, sec format in JavaScript?

seconds = Math.floor((totalHours / 1000) % 60),
minutes = Math.floor((totalHours / (1000 * 60)) % 60),
hours = Math.floor((totalHours / (1000 * 60 * 60)));
$("#showDispHours").text(hours + ':' + minutes);
Always Helping
  • 14,316
  • 4
  • 13
  • 29
Glyn
  • 1,933
  • 5
  • 37
  • 60
  • No worries. Deleting my working answer (as per this question) since it did NOT helped you and you never mentioned anything about scouts and the number `30` – Always Helping Aug 16 '20 at 04:12
  • Hi Always, it was a good answer, except on testing I found that it did not go past 24 hours. I will update the question to make this clear. Thank you for your help :-) – Glyn Aug 16 '20 at 04:24
  • Thank you! Please try to add all the information before the question is added so the person spending time on giving a working solution can includes all the scenarios you have mentioned initially! I can provide a solution for time going past 24 hours into the next day as well. Let me know. Please add it in the question. I am happy to help :) – Always Helping Aug 16 '20 at 04:26
  • Hi Always, I have found the remaining piece. Please put your answer back so I can accept it. – Glyn Aug 16 '20 at 05:04
  • I have added my answer back @Glyn. Thank you so much! – Always Helping Aug 16 '20 at 05:19

1 Answers1

1

You can use .clone() function of moment with duration() to add two times together. Get the times value in HH:mm using forEach and then on each loop add the value to the totalHours var and use hours() and minutes() function to display the total of all the times you want to add.

Live Demo:

let totalHours = 0;

let getTime = $('.fundTime') //get the el
//get the value stored as time
getTime.each(function(i, el) {
  let value = el.value //get value of i.e time
  if (moment(value, "HH:mm").isValid()) {
    let start = moment(value, 'HH:mm');
    let diff = start.diff(start.clone().startOf('day'));
    totalHours += diff;
  }
})

let duration = moment.duration(totalHours); //get total
$("#total").text(duration.hours() + ':' + duration.minutes());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>

<input type="text" class="fundTime" value="1:31" />
<input type="text" class="fundTime" value="3:00" />


<div id="total"></div>
Always Helping
  • 14,316
  • 4
  • 13
  • 29
  • Hi Always, almost there. Issue is that total hours can not be above 24. If I have 30 scouts working in shifts of 2 hours each this does not provide the answer I require :-) – Glyn Aug 16 '20 at 04:09