我相信我的算法不适合计算持续时间

时间:2012-01-09 11:13:31

标签: javascript jquery

我有一个算法,它计算剩余的总持续时间。持续时间的格式为'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);
}

谢谢

2 个答案:

答案 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