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

u0867587 used Ask the Experts™
on
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);

}
``````

Comment
Watch Question

Do more with

EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
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

Commented:
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;

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

Commented:
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).

Commented:
To answer your second question: No, i don't think you have to change anything else.

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);

Commented:
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;

...
``````

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?
Commented:
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);
}
``````

Commented:
Hi, I have completlely changed my algorithm now so I will be using that but this algorithm did help me

Do more with

Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.