我有一个算法,它计算剩余的总持续时间。持续时间的格式为'00小时00分00秒'。计算的工作原理如下:
如果总持续时间重新为01小时30分20秒并且用户输入持续时间00小时50分钟00秒并添加行,然后01小时30分钟20秒减去00小时50分钟00秒将使新的总持续时间剩余等于00小时40分20秒。
如果总持续时间变为负数,则格式如下: - 00小时00分00秒
我有几个问题:
问题1:
让我们说剩余的总持续时间是'00小时00分50秒'。然后,如果我将00小时00分50秒加两次,剩余的总持续时间应该等于' - 00小时00分50秒'
但相反它显示' - 00小时01分钟0-10秒'。
问题2:
让我们说总剩余时间是'00小时50分00秒'。然后,如果我两次添加00小时50分钟00秒,剩余的总持续时间应该等于' - 00小时50分00秒'
但是显示这个' - 01小时0-10分00秒。
这是一个奇怪的问题。但我相信这个问题正在发生,因为我的算法。所以我的问题是,如果算法有问题,有没有人知道如何解决这个问题呢?
以下是代码:
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);
});
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);
}
谢谢
答案 0 :(得分:1)
奇怪表示法的问题是因为你在这些行中进行字符串连接:
checkedH = (newH < 10 ? '0' : '') + newH;
checkedM = (newM < 10 ? '0' : '') + newM;
checkedS = (newS < 10 ? '0' : '') + newS;
如果秒数/分钟/小时是负数,则显然是< 10因此它将被添加到'0'。您的分钟数为负数的原因确实是算法中的错误。
我设置它的方法是,不是单独检查所有值,而是转换为总秒数,进行计算并转换回来。像这样:
tmp_secs= parseInt(tmp_format[0], 10) * 3600
+ parseInt(tmp_format[1], 10) * 60
+ parseInt(tmp_format[2], 10);
old_secs= hours * 3600 + mins * 60 + secs;
new_secs= old_secs-tmp_secs;
new_duration= (new_secs<0?'-':'') + Math.floor(new_secs/3600) + ' Hrs '
+ Math.floor((new_secs%3600)/60) + ' Mins '
+ Math.floor(new_secs%60) + ' Secs';
希望它有所帮助。
修改强>
用以下内容替换calculateDuration函数的内容:
var tmp_secs= 0;
var old_secs= hours * 3600 + mins * 60 + secs;
$("#qandatbl td.duration input").each(function (){
tmp_secs += parseInt(tmp_format[0], 10) * 3600
+ parseInt(tmp_format[1], 10) * 60
+ parseInt(tmp_format[2], 10);
}
new_secs= old_secs-tmp_secs;
abs_secs= Math.abs(new_secs);
new_duration= (new_secs<0?'-':'') + Math.floor(abs_secs/3600) + ' Hrs '
+ Math.floor((abs_secs%3600)/60) + ' Mins '
+ Math.floor(abs_secs%60) + ' Secs';
$("#total-duration").text(new_duration);
我没有对此进行测试,但我认为它应该可行。祝你好运!
答案 1 :(得分:1)
更新回答
重写了算法以仅处理秒数
var format = duration.match(/(\d\d)/ig),
hours = parseInt(format[0], 10),
mins = parseInt(format[1], 10),
secs = parseInt(format[2], 10);
function secondsFromTime(timeString){
var format = timeString.match(/(\d\d)/ig),
h = parseInt(format[0], 10),
m = parseInt(format[1], 10),
s = parseInt(format[2], 10);
return (h*3600) + (m*60) + s;
}
function calculateDuration()
{
var totalduration = secondsFromTime(duration);
var sign = '';
var durationchange = 0;
$("#qandatbl td.duration input").each(function (){
durationchange += secondsFromTime(this.value);
});
sign = (totalduration < durationchange ) ? '-' : '';
finalduration = Math.abs(totalduration - durationchange);
checkedH = ('0' + Math.floor(finalduration / 3600)).slice(-2);
checkedM = ('0' + Math.floor((finalduration % 3600) / 60)).slice(-2);
checkedS = ('0' + Math.floor(finalduration % 60)).slice(-2);
new_duration = sign + checkedH + ' Hrs ' + checkedM + ' Mins ' + checkedS + ' Secs';
$("#total-duration").text(new_duration);
}
演示 http://jsfiddle.net/gaby/4xjcW/1/
原始回答
使用Math.abs
获取绝对值..
checkedH = (Math.abs(newH) < 10 ? '0' : '') + Math.abs(newH);
checkedM = (Math.abs(newM) < 10 ? '0' : '') + Math.abs(newM);
checkedS = (Math.abs(newS) < 10 ? '0' : '') + Math.abs(newS);
问题是,您将0
作为字符串返回并添加-10
,使其变为0-10