3

我正在尝试编写一个可以执行以下操作的代码:

  1. 计算一行中两个type="time"元素之间的时间差(采用 HH:MM 格式)。
  2. 求和文本输入中的总差异(以 HH:MM 格式)。

我设法创建了一个由onchange事件触发的函数,但我的函数只考虑输入的第一个值,这意味着当您更新时间时,将重新计算差异并且总数将是错误的。

截屏

这是我用于计算第一行的 JavaScript 代码:

function CalTime0() {
    var timeOfCall = $('#timefrom0').val(),
    timeOfResponse = $('#timeto0').val(),
    hours = timeOfResponse.split(':')[0] - timeOfCall.split(':')[0],
    minutes = timeOfResponse.split(':')[1] - timeOfCall.split(':')[1],
    total = $('#tbtotal').val(),
    tothours = total.split(':')[0],
    totminutes = total.split(':')[1];               
    minutes = minutes.toString().length<2?'0'+minutes:minutes;
    totminutes = totminutes.toString().length<2?'0'+totminutes:totminutes;

    if(minutes<0) { 
        hours--;
        minutes = 60 + minutes;
    }

    hours = hours.toString().length<2?'0'+hours:hours;
    tothours = tothours.toString().length<2?'0'+tothours:tothours;
    tothours = parseInt(tothours) + parseInt(hours);
    totminutes = parseInt(totminutes) + parseInt(minutes);

    if(totminutes >= 60) { 
        tothours++;
        totminutes = totminutes - 60;
    }

    $('#total0').val(hours + ':' + minutes);    
    $('#tbtotal').val(tothours + ':' + totminutes); 
}
4

2 回答 2

1

The solution is to substract the time the #total0 field represents from the time the #tbtotal field represents. Then you calculate the new #total0 field, and add that time to #tbtotal again. This way the time displayed in #tbtotal is always correct.

The other question seemed to be how to do this for all rows, instead of just this one. You can use the this keyword to figure out what element fired the change event. From there you can figure out what the other elements would be. For this purpose I renamed the fields to timefr0 and timeto0, so they are equal length.

I took the liberty to convert all times to seconds, and manipulate them that way. The comments in the script should speak for themselfs.

function updateTotals() {
  //Get num part of the id from current set
  //Cheated a bit with the id names ;-)
  var num = $(this).attr('id').substr( 6 );

  //Get the time from each and every one of them
  var tfrom = $('#timefr' + num ).val().split(':');
  var tto = $('#timeto' + num ).val().split(':');
  var currtotal = $('#total' + num ).val().split(':');
  var grandtotal = $('#tbtotal').val().split(':');

  //Convert to seconds and do the calculations the easy way
  var diff = (tto[0] - tfrom[0]) * 3600 + (tto[1] - tfrom[1]) * 60;
  var totalsec = currtotal[0] * 3600 + currtotal[1] * 60;
  var grandtotalsec = grandtotal[0] * 3600 + grandtotal[1] * 60;

  //If the result is negative, we can't do anything sensible. Use 0 instead.
  if( diff < 0 ) {
    diff = 0;
  }

  //Substract what we calculated last time
  grandtotalsec -= totalsec;
  //Then add the current diff
  grandtotalsec += diff;

  //Convert diff (or total) into human readable form
  var hours = Math.floor( diff / 3600 );
  diff = diff % 3600;
  var minutes = Math.floor( diff / 60 );

  hours = (hours < 10) ? "0" + hours.toString() : hours.toString();
  minutes = (minutes < 10) ? "0" + minutes.toString() : minutes.toString();


  //Convert grandtotal into human readable form
  var grandtotalhours = Math.floor( grandtotalsec / 3600 );
  grandtotalsec = grandtotalsec % 3600;
  var grandtotalminutes = Math.floor( grandtotalsec / 60 );

  grandtotalhours = (grandtotalhours < 10) ? "0" + grandtotalhours.toString() : grandtotalhours.toString();
  grandtotalminutes = (grandtotalminutes < 10) ? "0" + grandtotalminutes.toString() : grandtotalminutes.toString();  

  //Put them in the fields
  $( '#total' + num ).val( hours + ":" + minutes );
  $( '#tbtotal' ).val( grandtotalhours + ":" + grandtotalminutes );
}

An example fiddle can be found here.

于 2013-10-27T18:14:45.187 回答
1

作为建议,要更轻松地计算日期差异,请使用 moment.js。日期差异计算应该可以用类似这样的东西替换,用时刻:

moment(timeOfResponse).diff(moment(timeOfCall))

moment.js 差异文档:http ://momentjs.com/docs/#/displaying/difference/

于 2013-10-27T16:59:03.197 回答