我已经启动并运行了一个数据表,目前我已经通过添加手动定义了日期格式
$.fn.dataTable.moment("DD.MM.YYYY");
在定义我的数据表本身之前:
var myTable = $('#authors').DataTable({
"paging": false,
"ordering": true,
"order": [2, "desc"],
"info": false,
"stateSave": true,
"responsive": true,
"columnDefs": [
{ targets: "noSort", orderable: false }
]
});
如您所见,我们目前使用的是德语日期格式。但可能是我们必须在当年晚些时候使用其他格式。
有没有办法自动检测给定日期列的值,以便我可以正确排序该列?还是我总是必须手动定义日期格式?
我想要的是一种动态版本的线
$.fn.dataTable.moment("DD.MM.YYYY");
它应该检测到“哦,该列中的值是 '29.04.2019',这是德国日期格式,定义为 dd.mm.yyyy”,并使用此格式进行进一步排序。
或者,如果值为“04/29/2019”,则应将其识别为美国日期格式,使用“mm/dd/yyyy”进行排序。
目前我不知道应用程序将支持多少种不同的日期格式。我想这将是5个或更多。但是在单个表中,只会使用一种格式。
最佳答案
建议您将格式数组传递给 $.fn.dataTable.moment(...)
,但是当且仅当数据永远不会匹配数组中的一种以上格式时才有效。除非你能保证这一点,否则传递格式数组不是解决方案。
您从 DD.MM.YYYY
的示例开始。和 MM/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
中的日期。格式,包含以下单元格:
表 2
假设一个表打算使用
MM/DD/YYYY
中的日期。格式,包含以下单元格:这两个表实际上包含相同的日期。它们只是表示方式不同。
假设您使用
$.fn.dataTable.moment(["DD/MM/YYYY", "MM/DD/YYYY"])
配置您的表.表 1 将被正确解释。但是,无法正确解释表 2 中的第 2 行。日期4/1/2019
确实适合数组中的第一种格式( DD/MM/YYYY
),这就是 moment
的方式会解释它。没有多少其他单元格无法容纳DD/MM/YYYY
因为调用 moment
的插件不做统计分析。它孤立地查看每个单元格。这是相关的code (删除了一些空行):$.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 );
};
};
您可以翻转参数并调用
$.fn.dataTable.moment(["MM/DD/YYYY", "DD/MM/YYYY"])
.现在第二张 table 会很好,但同样的问题会发生在第一张 table 上。好的,然后呢?
如果后端恰好已经包含 UTC 时间戳,那么我只需将这些时间戳发送到前端,而不是发送本地化值。在呈现包含日期的单元格的阶段,我会让前端将 UTC 日期转换为对用户有意义的格式。 Datatable 将根据 UTC 值进行排序,可以毫无歧义地进行比较。
如果后端不将其日期存储为 UTC 时间戳,我将重新设计它以便它这样做,然后执行我在上一段中描述的操作。
否则,可能有一种方法可以在 Datatables 尝试呈现和排序之前在前端对表进行统计分析。因此,您可以发现使用哪种格式,然后将其提供给 Datatables。但是,这对我来说仍然很脆弱。如果表使用服务器端协议(protocol),那么一次只有一小部分数据可用。如果您仅对来自服务器的第一个响应进行分析,则覆盖表后面部分的稍后响应可能会反驳最初的假设。此外,可能存在数据表中的所有日期不明确的情况。在大型且未过滤的数据集上,这可能不太可能,但一旦允许用户过滤数据集以仅显示子集,他们可能会以导致特定子集中的所有日期不明确的方式对其进行过滤。我不会部署应用程序,希望这永远不会发生。
关于javascript - jQuery 数据表 : is there a way to detect date format automatically?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55455805/