jQuery DataTables:有没有一种方法可以自动检测日期格式?

Jon*_*now 3 javascript jquery datatables momentjs

我已经启动并运行了一个数据表,目前我已经通过添加手动定义了日期格式

$.fn.dataTable.moment("DD.MM.YYYY");
Run Code Online (Sandbox Code Playgroud)

在定义数据表本身之前:

var myTable = $('#authors').DataTable({
    "paging": false,
    "ordering": true,
    "order": [2, "desc"],
    "info": false,
    "stateSave": true,
    "responsive": true,
    "columnDefs": [
        { targets: "noSort", orderable: false }
    ]       
});
Run Code Online (Sandbox Code Playgroud)

如您所见,我们目前正在使用德语日期格式。但是有可能在那年晚些时候我们不得不使用其他格式。

有没有一种方法可以自动检测给定日期列的值,以便我可以对该列进行正确排序?还是我总是必须手动定义日期格式?

我想要的是该系列的动态版本

$.fn.dataTable.moment("DD.MM.YYYY");
Run Code Online (Sandbox Code Playgroud)

它应检测到“哦,该列中的值为'29 .04.2019',这是德语日期格式,定义为dd.mm.yyyy”,并使用此格式进行进一步排序。

或者,如果值改为“ 04/29/2019”,则应将其识别为美国日期格式,并使用“ mm / dd / yyyy”进行排序。

目前,我不知道该应用程序将支持多少种不同的日期格式。我想它将是5个或更多。但是在一个表中,将仅使用一种格式。

Lou*_*uis 5

建议您将一个数组用于格式传递给$.fn.dataTable.moment(...),但这仅在且永远不会发生数据匹配数组中多个格式的情况下才有效。除非您能保证这一点,否则传递格式数组不是解决方案。

您开始使用的例子DD.MM.YYYYMM/DD/YYYY。日期将匹配任何一种格式,但不能同时匹配两者,因为日期如果具有句点定界符而不是第一种格式,但不能匹配第二种,并且如果具有斜杠定界符,则它与第二种格式匹配,而不与第一种格式匹配。但是,通常来说,如果您的约会日期不是美国或德国以外的其他地方,您就会遇到模棱两可的情况。例如,马特·约翰逊(Matt Johnson)提到了一个日期,例如“ 01/04/2019”,该日期可以适合MM/DD/YYYY格式并解释为“ 2019年1月4日”,也可以适合DD/MM/YYYY格式并解释为“ 2019年4月1日”。

如果您可以使用日期格式DD/MM/YYYY或日期MM/DD/YYYY格式来致电,$.fn.dataTable.moment(["DD/MM/YYYY", "MM/DD/YYYY"])那么有时您会得到不正确的结果。问题是,它实现了功能你调用看起来在每个单元插件隔离

表格1

假设要使用DD/MM/YYYY格式为日期的表格包含以下单元格:

  1. 21/2/2019
  2. 1/4/2019
  3. 24/12/2019

表2

假设要使用MM/DD/YYYY格式为日期的表格包含以下单元格:

  1. 2/21/2019
  2. 4/1/2019
  3. 12/24/2019

这两个表实际上包含相同的日期。它们只是代表不同。

假设您使用配置了表格$.fn.dataTable.moment(["DD/MM/YYYY", "MM/DD/YYYY"])。表1将被正确解释。但是,表2中的第2行将无法正确解释。日期4/1/2019确实适合数组(DD/MM/YYYY)中的第一种格式,这就是moment将其解释的方式。DD/MM/YYYY因为调用的插件moment不进行统计分析,所以可以容纳多少其他单元也无关紧要。它隔离地查看每个单元。以下是相关代码(删除了一些空白行):

$.fn.dataTable.moment = function ( format, locale, reverseEmpties ) {
    var types = $.fn.dataTable.ext.type;

    // Add type detection
    types.detect.unshift( function ( d ) {
        if ( d ) {
            // Strip HTML tags and newline characters if possible
            if ( d.replace ) {
                d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
            }

            // Strip out surrounding white space
            d = $.trim( d );
        }

        // Null and empty values are acceptable
        if ( d === '' || d === null ) {
            return 'moment-'+format;
        }

        return moment( d, format, locale, true ).isValid() ?
            'moment-'+format :
            null;
    } );

    // Add sorting method - use an integer for the sorting
    types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
        if ( d ) {
            // Strip HTML tags and newline characters if possible
            if ( d.replace ) {
                d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
            }

            // Strip out surrounding white space
            d = $.trim( d );
        }

        return !moment(d, format, locale, true).isValid() ?
            (reverseEmpties ? -Infinity : Infinity) :
            parseInt( moment( d, format, locale, true ).format( 'x' ), 10 );
    };
};
Run Code Online (Sandbox Code Playgroud)

您可以翻转参数并调用$.fn.dataTable.moment(["MM/DD/YYYY", "DD/MM/YYYY"])。现在第二张表就可以了,但是在第一张表中也会发生同样的问题。


好的,那怎么办?

如果后端恰好已经包含UTC时间戳,那么我只是将这些时间戳发送到前端,而不是发送本地化的值。在渲染包含日期的单元格的阶段,我将让前端将UTC日期转换为对用户有意义的格式。数据表将根据UTC值进行排序,可以毫无歧义地对其进行比较。

如果后端未将其日期存储为UTC时间戳,那么我将对其进行重新设计,使其能够正确执行,然后执行上一段中所述的操作。

否则,可能在Datatables尝试呈现和排序之前,最好在前端对表格进行统计分析。因此,您可以发现使用哪种格式,然后将其提供给数据表。但是,这对我来说仍然很脆弱。如果表使用服务器端协议,则一次仅一小部分数据可用。如果仅对服务器的第一个响应进行分析,则覆盖表后半部分的后一个响应可能会反驳初始假设。此外,在某些情况下,数据表中的所有日期可能都不明确。在大型且未经过滤的数据集上,这种情况不太可能发生,但是一旦允许用户过滤数据集以仅显示子集,他们就可能以导致特定子集中的所有日期不明确的方式对其进行过滤。