When numbers go negative, it is displaying the "-" sign in the wrong place sometimes

I have an application where use selects their duration and then adds it to a new row. Now the duration performs a calculation between the total duration and the duration in the added rows. So for example if total duration was 00 Hrs 00 Mins 25 Secs and the duration in the added row is 00 Hrs 00 Mins 10 Secs, then 00 Hrs 00 Mins 25 Secs minus 00 Hrs 00 Mins 10 Secs equals 00 Hrs 00 Mins 15 Secs for total duration remaining.

If the total duration remaining goes into negative then it is suppose to display a minus in fromt of the duration like so:

-10 Hrs 50 Mins 45 Secs

It does display this but sometimes it does something wierd. It sometimes display this when it goes to the negatives:

00 Hrs 00 Mins 0-25 Secs

or

00 Hrs 0-30 Mins 00 Secs

I don't know why it is doing this. I am trying to figure out a pattern on why this is happening but I can't.

If you click here then you will be able to use my application. follow these steps below in application and you will be able to see what is happening:

1. You will see a textbox and below that the total duration remaining 00 Hrs 01 Mins 20 Secs. click on the clock button and select 00 Hrs 00 Mins 50 Secs by just using the sliders.

2: Click on the "Add Question" button. The duration you entered in the row is displayed in a new row below and you will see total duration change to 00 Hrs 00 Mins 30 Secs.

3. Now click on the "Add Question" button again to add 00 Hrs 00 Mins 50 Secs again from the top in a new row. You will now have to rows showing 00 Hrs 00 Mins 50 Secs, yet the total duration remaining says 00 Hrs 00 Mins 0-20 Secs. This should display - 00 Hrs 00 Mins 20 Secs.

I don't why it is doing this, does anyone know why?

Jquery code which performs calculation is below (to view full code then please go on the view page source on the browser:

var format = duration.match(/(\d\d)/ig),
hours = parseInt(format[0], 10),
mins = parseInt(format[1], 10),
secs = parseInt(format[2], 10);

function calculateDuration()
{
    var totalduration = duration;  
    var sign = '';
    var tmp_hours = 0;
    var tmp_mins = 0;
    var tmp_secs = 0;

    $("#qandatbl td.duration input").each(function (){
        tmp_format = $(this).val().match(/(\d\d)/ig),
        tmp_hours += parseInt(tmp_format[0], 10),
        tmp_mins += parseInt(tmp_format[1], 10),
        tmp_secs += parseInt(tmp_format[2], 10);

    });

    newH = hours - tmp_hours;
    newM = mins - tmp_mins;
    newS = secs - tmp_secs;

    if( newS < 0 ) {
        newS += 60;
        newM--;
    }
    if( newM < 0 ) {
        newM += 60;
        newH--;
    }       

    if(newH < 0) {
        newH = tmp_hours - hours;
        newM = tmp_mins - mins;
        newS = tmp_secs - secs;
        if( newS < 0 ) {
            newS += 60;
            newM--;
        }
        if( newM < 0 ) {
            newM += 60;
            newH--;
        }       
        sign = '- ';
    }       

    checkedH = (newH < 10 ? '0' : '') + newH;
    checkedM = (newM < 10 ? '0' : '') + newM;
    checkedS = (newS < 10 ? '0' : '') + newS;

    new_duration = sign + checkedH + ' Hrs ' + checkedM + ' Mins ' + checkedS + ' Secs';


    $("#total-duration").text(new_duration);

}

Open in new window


u0867587Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DerSpinnerCommented:
On every click you call your insertQuestion function which adds another row to your question duration table below.

You take the values from this table for the calculation of your tmp_ values which causes the problem that your tmp_secs are 100 if you run caculateDuration the second time. Your table rows are added instantly (onClick event) in the duration table on the bottom of the page and you have 2 rows if you run your .each loop which sums up to 100 seconds. Your bewS value is -20 because your have secs - tmp_secs = 20 - 100 = -80. -80 is lower than 0 but just adding +60 makes it -20 which is what you get on the screen.

You cannot just add 60 to your newS, newM to resolve the negative sign. You have to recalculate these values after running the .each loop, e.g.

This is what you have after calling the .each loop the second time:

tmp_hours = 0
tmp_mins = 0
tmp_secs = 100

you have to convert this to:

tmp_hours = 0
tmp_mins = 1
tmp_secs = 40

With these values the rest of your code will work and you will get "- 00 Hrs 00 Mins 20 Secs" as output.

BR
0
DerSpinnerCommented:
You could convert your values by using the modulo operator:

tmp_mins += tmp_secs / 60;
tmp_secs = tmp_secs % 60;
tmp_hours += tmp_mins / 60;
tmp_mins = tmp_mins % 60;
0
u0867587Author Commented:
Hi do you know the modulo operetor you have shown, how will in fit that in my code. IN other words if I include that,  then do I have to change anything else in the calculation code
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

DerSpinnerCommented:
Insert the following code after your .each loop to convert your tmp_ values:

tmp_mins += Math.floor(tmp_secs / 60);
tmp_secs = tmp_secs % 60;
tmp_hours += Math.floor(tmp_mins / 60);
tmp_mins = tmp_mins % 60;

The modulo operator (%) returns the remainder of the division (e.g. 3 % 2 = 1).
0
DerSpinnerCommented:
To answer your second question: No, i don't think you have to change anything else.
0
u0867587Author Commented:
Do I need to remove this then with the modulo code u given me:
         tmp_hours += parseInt(tmp_format[0], 10),
        tmp_mins += parseInt(tmp_format[1], 10),
        tmp_secs += parseInt(tmp_format[2], 10);
0
DerSpinnerCommented:
nono, this is what i meant (my code between the .each loop and your newX assignments):



...

$("#qandatbl td.duration input").each(function (){
        tmp_format = $(this).val().match(/(\d\d)/ig),
        tmp_hours += parseInt(tmp_format[0], 10),
        tmp_mins += parseInt(tmp_format[1], 10),
        tmp_secs += parseInt(tmp_format[2], 10);
});

// new code HERE
tmp_mins += Math.floor(tmp_secs / 60);
tmp_secs = tmp_secs % 60;
tmp_hours += Math.floor(tmp_mins / 60);
tmp_mins = tmp_mins % 60;

newH = hours - tmp_hours;
newM = mins - tmp_mins;
newS = secs - tmp_secs;

...

Open in new window

0
u0867587Author Commented:
Hi,

It does sort out the format for the negative but there is  one slight problem;

lets say total duration remaining is 01 Hrs 30 Mins 20 Secs

Then if I add 2 rows, both 00 Hrs 50 Mins 00 secs

Then total duration remaining should equal - 00 Hrs 10 Mins 20 Secs
But Instead it displays this - 00 Hrs 09 Mins 40 Secs

Why is it doing this?
0
DerSpinnerCommented:
I've checked the algorithm again and it seems there is another problem. You can simplify the block checking if the newH is lower than 0. This is the whole function:

function calculateDuration()
{
    var totalduration = duration;  
    var sign = '';
    var tmp_hours = 0;
    var tmp_mins = 0;
    var tmp_secs = 0;

    $("#qandatbl td.duration input").each(function (){
        tmp_format = $(this).val().match(/(\d\d)/ig),
        tmp_hours += parseInt(tmp_format[0], 10),
        tmp_mins += parseInt(tmp_format[1], 10),
        tmp_secs += parseInt(tmp_format[2], 10);

    });
    
    tmp_mins += Math.floor(tmp_secs / 60);
    tmp_secs = tmp_secs % 60;
    tmp_hours += Math.floor(tmp_mins / 60);
    tmp_mins = tmp_mins % 60;

    newH = hours - tmp_hours;
    newM = mins - tmp_mins;
    newS = secs - tmp_secs;

    if( newS < 0 ) {
        newS += 60;
        newM--;
    }
    if( newM < 0 ) {
        newM += 60;
        newH--;
    }       

    if(newH < 0) {
        newM = Math.abs(newM - 60);
        newH = Math.abs(newH + 1);
        
        sign = '- ';
    }       

    checkedH = (newH < 10 ? '0' : '') + newH;
    checkedM = (newM < 10 ? '0' : '') + newM;
    checkedS = (newS < 10 ? '0' : '') + newS;

    new_duration = sign + checkedH + ' Hrs ' + checkedM + ' Mins ' + checkedS + ' Secs';

    $("#total-duration").text(new_duration);
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
u0867587Author Commented:
Hi, I have completlely changed my algorithm now so I will be using that but this algorithm did help me
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
jQuery

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.