有人建议将格式数组传递给
$.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
格式的日期,具有以下单元格:
- 21/2/2019
- 1/4/2019
- 24/12/2019
表2:假设一个表格要使用
MM/DD/YYYY
格式的日期,具有以下单元格:
- 2/21/2019
- 4/1/2019
- 12/24/2019
这两个表格实际上包含相同的日期,只是表示方式不同。
假设您使用
$.fn.dataTable.moment(["DD/MM/YYYY", "MM/DD/YYYY"])
配置了表格。表格1将被正确解释。然而,表格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;
types.detect.unshift( function ( d ) {
if ( d ) {
if ( d.replace ) {
d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
}
d = $.trim( d );
}
if ( d === '' || d === null ) {
return 'moment-'+format;
}
return moment( d, format, locale, true ).isValid() ?
'moment-'+format :
null;
} );
types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
if ( d ) {
if ( d.replace ) {
d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
}
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"])
。现在第二个表格将正常显示,但是第一个表格将发生相同的问题。
好的,那接下来呢?
如果后端已经包含了UTC时间戳,那么我会将这些时间戳发送到前端,而不是发送本地化的值。在渲染包含日期的单元格时,我会让前端将UTC日期转换为对用户有意义的格式。Datatable将根据UTC值进行排序,这些值可以无歧义地进行比较。
如果后端没有将其日期存储为UTC时间戳,我会重新设计它以使其支持,并执行我在上一段中描述的操作。
否则,在Datatables尝试呈现和排序表格之前,可能有一种方法在前端对您的表格进行统计分析。因此,您可以发现使用的格式,然后将其提供给Datatables。但是,这对我来说仍然似乎很脆弱。如果表格使用服务器端协议,则每次只有一小部分数据可用。如果您仅对服务器的第一个响应进行分析,则稍后覆盖表格的后面部分的响应可能会驳斥最初的假设。此外,可能存在所有日期在datatable中都是模糊的情况。在大型未过滤的数据集上,这可能不太可能,但是一旦允许用户过滤数据集以仅显示子集,他们可能以导致特定子集中所有日期都不明确的方式过滤它。我不会部署希望永远不会发生这种情况的应用程序。