Javascript hh:mm:ss的jQuery Datatables列总和()

Javascript hh:mm:ss的jQuery Datatables列总和(),javascript,jquery,time,datatables,momentjs,Javascript,Jquery,Time,Datatables,Momentjs,我正在使用jquerydatatables,需要对一个时间(hh:mm:ss)列求和 我使用sum()插件()添加列数据,但我并不真正了解它的工作原理 var time_api = this.api(); //total var total = time_api.column(3) .data() .sum(); //fo

我正在使用jquerydatatables,需要对一个时间(hh:mm:ss)列求和

我使用sum()插件()添加列数据,但我并不真正了解它的工作原理

        var time_api = this.api();
        //total
        var total = time_api.column(3)
                .data()
                .sum();           
            
        //footer
        $(time_api.column(3)
            .footer())
            .html(total);
这给了我一个求和的输出,但它需要一些调整,我想不出如何将其转换为:

这是:12:03:05(正确的总和输出)

请提供帮助。

如中所示,它首先将字符串单元格内容转换为数字,然后执行加法。您应该通过解析格式化值HH:MM:SS(例如,通过regexp)来扩展单元格值的处理,然后将其转换为以秒为单位的时间间隔(HH*24+MM*60+SS),然后将这些值相加,然后将其转换回小时/分/秒

您可以像这样更新
sum
函数:

jQuery.fn.dataTable.Api.register( 'sum()', function ( ) {
    return this.flatten().reduce( function ( a, b ) {

        var timeRegexp = /^(\d{2}):(\d{2}):(\d{2})$/

        var matches = a.match(timeRegexp);
        if (matches) {
            var hh = matches[1], mm = matches[2], ss = matches[3];
            var intervalAsSeconds = hh * 24 + mm * 60 + ss;
            return b + intervalAsSeconds;
        }

        if ( typeof a === 'string' ) {
            a = a.replace(/[^\d.-]/g, '') * 1;
        }
        if ( typeof b === 'string' ) {
            b = b.replace(/[^\d.-]/g, '') * 1;
        }

        return a + b;
    }, 0 );
} );
要将秒数总和转换回HH:MM:SS,可以使用以下功能:

function secondsToTime(seconds) {
  var hours = Math.floor(seconds / 3600);
  var minutes = Math.floor((seconds % 3600) / 60); 
  var seconds = Math.floor(seconds % 60);
  return (hours < 10 ? "0" + hours : hours) + ":" + 
         (minutes < 10 ? "0" + minutes : minutes) + ":" + 
         (seconds < 10 ? "0" + seconds : seconds);
}

此解决方案适用于

var time_api=this.api();
var总计=速度列(3)
.data()
.sum();
total=total.toString();
而(总长度<6){
tempoTotal=“0”+tempoTotal
}    
总计=总计。替换(/^(\d+)(\d{2})(\d{2})$/,函数(m,m1,m2,m3){
m1=数字(m1);//将捕获的组值转换为数字
m2=数量(m2);
m2+=parseInt(m3/60,10);//从秒开始获取分钟数,并将其添加到分钟数
m3=m3%60;//获取soconds
m1+=parseInt(m2/60,10);//从分钟中获取分钟并将其添加到小时中
m2=m2%60;//获取分钟数
//将0添加到分钟和秒,如果是一位数,则片(-2)将选择最后2位数
返回m1+':'+('0'+m2).slice(-2)+':'+('0'+m3.slice(-2);//返回更新的字符串
})
//用页脚书写
$(节奏栏(3)
.footer())
.html(总计);

变量表=$('#示例')。数据表({
“footerCallback”:函数(行、数据、开始、结束、显示){
var api=this.api(),数据;
//总页数
total_ID=api.column(0.data().reduce(函数a,b){
返回~~a+~~b;
}, 0 );
total_Duration=api.column(1.data().reduce(函数a,b){
返回时刻.duration(a).asmillseconds()+时刻.duration(b).asmillseconds();
}, 0 );
//本页总计
pageTotal_ID=api.column(0,{page:'current'}).data().reduce(函数(a,b){
返回~~a+~~b;
}, 0 );
pageTotal_Duration=api.column(1,{page:'current'}).data().reduce(函数(a,b){
返回时刻.duration(a).asmillseconds()+时刻.duration(b).asmillseconds();
}, 0 );
//更新页脚列“quantita”
$(api.column(0.footer()).html(
pageTotal_-ID+'('+total_-ID+'total)'
);
$(api.column(1.footer()).html(
time.utc(pageTotal_Duration).format(“HH:mm:ss”)+”(“+time.utc(total_Duration).format(“HH:mm:ss”)+“total”
);
}   
});

在这种情况下,我会变得有点棘手。使用
时间
创建一个隐藏列,但只使用
。现在,我可以使用此列计算
总数
,并将其转换回我需要的格式

    $('#tblTime').DataTable({
    "footerCallback": function (row, data, start, end, display) {

        var api = this.api();

        //convert seconds to hour:minute:seconds
        var secondsToHms = function(d) {
          d = Number(d);
          var h = Math.floor(d / 3600);
          var m = Math.floor(d % 3600 / 60);
          var s = Math.floor(d % 3600 % 60);

          return h + ":" + m + ":" + s;
        };

        //sum of hidden colunm hours in seconds
        var sum_hours_estimated = api
          .column( 2 ) //hidden column
          .data()
          .reduce( function (a, b) {
              return intVal(a) + intVal(b);
        }, 0 );

        //covert the seconds into hour.minute
        var hours_estimated = secondsToHms(sum_hours_estimated);   

        var summary = '<ul><li>Total Time ' + hours_estimated + '</li><ul>';
        $(api.column(1).footer()).html(summary);
    },
    //hide the column
    "columnDefs": [
        {
            "targets": [ 2 ],
            "visible": false,
            "searchable": false
        }
    ]
});

//Use this if "columnDefs" doesn't work
$('#tblTime').DataTable().column( 2 ).visible( false );
$('tblTime')。数据表({
“footerCallback”:函数(行、数据、开始、结束、显示){
var api=this.api();
//将秒转换为小时:分钟:秒
var secondsToHms=函数(d){
d=数量(d);
var h=数学楼层(d/3600);
var m=数学下限(d%3600/60);
var s=数学下限(d%3600%60);
返回h+“:“+m+”:“+s;
};
//以秒为单位的隐藏colunm小时的总和
var总和\小时\估计值=api
.column(2)//隐藏列
.data()
.减少(功能a、b){
返回intVal(a)+intVal(b);
}, 0 );
//把秒转换成小时。分钟
var小时数估计值=秒数(总小时数估计值);
风险值汇总=“
  • 总时间”+估计小时数+”
    • ; $(api.column(1.footer()).html(摘要); }, //隐藏列 “columnDefs”:[ { “目标”:[2], “可见”:假, “可搜索”:false } ] }); //如果“columnDefs”不起作用,请使用此选项 $('#tblTime').DataTable().column(2).可见(false);
我遇到了dsame问题,我找到了一个适合我的解决方案:

footerCallback: function ( row, data, start, end, display ) {
        var api = this.api(), data;

        var intVal = function ( i ) {
            return i != null ? moment.duration(i).asSeconds() : 0;
        };

        var total = api.column( 3 ).data()
            .reduce( function (a, b) {
            var total = intVal(a) + intVal(b);
            var totalFormatted = [
                parseInt(total / 60 / 60),
                parseInt(total / 60 % 60),
                parseInt(total % 60)
            ].join(":").replace(/\b(\d)\b/g, "0$1");
            return totalFormatted;
        }, 0 );

        jQuery(api.column( 3 ).footer()).html(total);
    }
});

你说把数字分成11:62:65,然后创建公式,使输出看起来像12:03:05?你有任何代码片段可以让我开始吗?谢谢答案已更新(添加单元格值到秒和返回到HH:MM:SS的转换)。这是纯javascript,我相信您也可以使用moment.js的一些助手函数(因为您在标记中提到了它)来更轻松地处理间隔。@Alexey上面的代码将错误作为TypeError抛出:a.match不是函数。任何解决方案?@Steffi datatables api可以更改,以便
this.flatte()…
可以返回集合以外的其他内容。请在调用.match()之前检查该类型和
a
,它应该是一个字符串。您可以添加一些说明吗?如果您不想添加sum js和api()然后,它可以通过javascript而不使用api。
<script type="text/javascript" language="javascript">

var table = $('#example').DataTable({
"footerCallback": function ( row, data, start, end, display ) {
    var api = this.api(), data;
    // Total over all pages
    total_ID = api.column(0).data().reduce( function (a, b) {
        return ~~a + ~~b;
    }, 0 );
    total_Duration = api.column(1).data().reduce( function (a, b) {
        return moment.duration(a).asMilliseconds() + moment.duration(b).asMilliseconds();
    }, 0 );
    // Total over this page
    pageTotal_ID = api.column(0, { page: 'current'} ).data().reduce( function (a, b) {
        return ~~a + ~~b;
    }, 0 );
    pageTotal_Duration = api.column(1, { page: 'current'} ).data().reduce( function (a, b) {
        return moment.duration(a).asMilliseconds() + moment.duration(b).asMilliseconds();
    }, 0 );
    // Update footer Column "quantita"
    $( api.column(0).footer()).html(
        pageTotal_ID + ' ('+ total_ID +' total)'
    );
    $( api.column(1).footer()).html(
        moment.utc(pageTotal_Duration).format("HH:mm:ss") + ' ('+ moment.utc(total_Duration).format("HH:mm:ss") + ' total)'
    );
}   
});
</script>
    $('#tblTime').DataTable({
    "footerCallback": function (row, data, start, end, display) {

        var api = this.api();

        //convert seconds to hour:minute:seconds
        var secondsToHms = function(d) {
          d = Number(d);
          var h = Math.floor(d / 3600);
          var m = Math.floor(d % 3600 / 60);
          var s = Math.floor(d % 3600 % 60);

          return h + ":" + m + ":" + s;
        };

        //sum of hidden colunm hours in seconds
        var sum_hours_estimated = api
          .column( 2 ) //hidden column
          .data()
          .reduce( function (a, b) {
              return intVal(a) + intVal(b);
        }, 0 );

        //covert the seconds into hour.minute
        var hours_estimated = secondsToHms(sum_hours_estimated);   

        var summary = '<ul><li>Total Time ' + hours_estimated + '</li><ul>';
        $(api.column(1).footer()).html(summary);
    },
    //hide the column
    "columnDefs": [
        {
            "targets": [ 2 ],
            "visible": false,
            "searchable": false
        }
    ]
});

//Use this if "columnDefs" doesn't work
$('#tblTime').DataTable().column( 2 ).visible( false );
footerCallback: function ( row, data, start, end, display ) {
        var api = this.api(), data;

        var intVal = function ( i ) {
            return i != null ? moment.duration(i).asSeconds() : 0;
        };

        var total = api.column( 3 ).data()
            .reduce( function (a, b) {
            var total = intVal(a) + intVal(b);
            var totalFormatted = [
                parseInt(total / 60 / 60),
                parseInt(total / 60 % 60),
                parseInt(total % 60)
            ].join(":").replace(/\b(\d)\b/g, "0$1");
            return totalFormatted;
        }, 0 );

        jQuery(api.column( 3 ).footer()).html(total);
    }
});