数据表格日期排序dd/mm/yyyy问题

106

我正在使用一个叫做 datatables 的 Jquery 插件。

它很棒,但是我无法按照 dd/mm/yyyy 的格式正确排序日期。

我查看了他们的支持格式,但没有任何解决方法能够解决这个问题。

请问这里有人可以帮我吗?


你看过这个吗:http://www.datatables.net/release-datatables/examples/plug-ins/sorting_plugin.html - xkeshav
我已经看过了,但不太明白如何将其应用于日期。我已经用破折号替换了正斜杠,但对其余部分不确定。它说它检查一个小数位,你怎么能让它检查两个破折号? - jaget
你没有提及加载数据的方法,所以我已经添加了一个 AJAX 解决方案。我发现我的大多数表格最初都是在浏览器中的数据,但最终都会迁移到 AJAX。 - Sablefoste
31个回答

173

更新2020: HTML解决方案

由于HTML 5已经得到广泛应用,并且几乎所有主流浏览器都支持它,因此现在更清晰的方法是使用HTML5数据属性 (maxx777提供了一个PHP解决方案,我正在使用简单的HTML)。对于我们场景中的非数字数据,可以使用data-sortdata-order属性并为其分配可排序值。

HTML

<td data-sort='YYYYMMDD'>DD/MM/YYYY</td>

这里是可用的HTML解决方案

jQuery解决方案

这里是可用的jQuery解决方案

jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"date-uk-pre": function ( a ) {
    var ukDatea = a.split('/');
    return (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
},

"date-uk-asc": function ( a, b ) {
    return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},

"date-uk-desc": function ( a, b ) {
    return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
 
将上述代码添加到脚本中,并使用 { "sType": "date-uk" }将特定的日期值列设置为日期类型,其他列设置为null,如下所示:
$(document).ready(function() {
    $('#example').dataTable( {
        "aoColumns": [
            null,
            null,
            null,
            null,
            { "sType": "date-uk" },
            null
        ]
    });
    });

1
我不知道我缺少什么,但这并没有正确地排序日期,即使在编辑后的链接中也是如此。 - Thousand
1
@Fede,实际上帖子中的链接是带有/edit的,最近已经更新了,我已经更正了链接。请注意它只是按照dd/mm/yyyy格式对日期进行排序。 - Zaheer Ahmed
2
如果您希望按字符串而不是数字排序日期,则必须删除“date-uk-pre”函数末尾的“* 1”,该函数将返回的日期转换为数字。通过这个更改,一切都像魅力一样! :) - Nicki Voutou
2
这是一个优雅的修复。 - athulpraj
2
CSS解决方案更好,谢谢。 - Alberto Acuña
显示剩余10条评论

124

日期排序 - 带有隐藏元素

将日期转换为格式YYYYMMDD并添加到实际值(DD/MM/YYYY)的<td>之前,将其包装在一个元素中,并将样式设置为display:none;。现在日期排序将像普通排序一样工作。同样的方法也可以应用于日期时间排序。

HTML

<table id="data-table">
   <tr>
     <td><span>YYYYMMDD</span>DD/MM/YYYY</td>
   </tr>
</table>

CSS

#data-table span {
    display:none; 
}

4
除了这个之外,什么都没用。(表示惊讶或满意)如果你在使用 Rails(idea 是我使用的模型名称),那么以下应该是你需要的代码: <%= idea.created_at.strftime("%Y%m%d") %> <%= idea.created_at.strftime("%d/%m/%Y") %> - matias salgado
8
很不幸,当您使用datatables导出pdf插件时,它会将所有的HTML标签(包括隐藏的HTML标签)也一并取出。导致导出的文件中数据重复。它还会导出<span>标签内的数据。 - Are0215
这实际上是如何工作的?DataTable库是否查看跨度而不是前置值? - Limyandi Vico Trico
@LimyandiVicoTrico YYYYMMDD格式是一个按日期排序的数字。 - Anulal S
太棒了!我在我的项目中使用Bootstrap,所以我可以使用d-none类代替单独的CSS规则:<span class='d-none'>...</span>... - Dan King
显示剩余5条评论

45

我知道这是一个老问题,回答也都很老了。最近我发现了一种简单而干净的排序日期的方法。可以通过在HTML5中将data-order属性添加到<td>元素中来实现。

以下是我在PHP中所做的:

<?php
$newdate = date('d M Y', $myDateTime); // Format in which I want to display
$dateOrder = date('Y-m-d', $myDateTime); // Sort Order
?>

<td data-order="<?php echo $dateOrder; ?>" >
<?php echo $newdate; ?>
</td>

4
这个功能的文档可以在这里找到:https://datatables.net/release-datatables/examples/advanced_init/html5-data-attributes.html - mitchdav
我使用了moment.js和datatable的render函数。 例如:"render": function(data, type, row){ if(type == 'sort'){ return moment(data,'DD-MM-YYYY').format('YYYY-MM-DD'); } else { return moment(data,'DD-MM-YYYY').format('MM/DD/YYYY'); } } - undefined

13

尝试使用此插件

此处所述,您需要包含 Moment.js 和 datatable-moment 插件,然后只需声明您正在使用的日期格式。 插件将自动检测您的日期列并按应有方式进行排序。 有关 moment.js 格式解释,请查看此处

示例:

$(document).ready(function() {
    $.fn.dataTable.moment('DD/MM/YYYY HH:mm');
    $('#example').DataTable();
});

如果包含时间怎么办? - Eli
@Eli 你尝试过 $.fn.dataTable.moment('DD.MM.YYYY HH.mm.ss'); 吗?这里的 HH.mm.ss 就是你的时间格式。更多信息 - mineroot
1
$.fn.dataTable.moment('YYYY.MM.DD HH.mm.ss'); 我使用了这个,但它没有起作用。 - Eli
我在表格中有一个“创建日期”列,但它并没有按照顺序排列。 - Eli
你的日期时间格式是像 2016.03.29 14.33.08 这样的吗?请参考示例部分。这完全取决于你的格式。 - mineroot
显示剩余5条评论

13

这是我的方法,它对我起了作用。

<td data-order="@item.CreatedOn.ToString("MMddyyyyHHmmss")">
    @item.CreatedOn.ToString("dd-MM-yyyy hh:mm tt")
</td>

data-order属性中,这个日期格式应该使用 DataTable 支持的格式。


1
我认为这应该被视为正确的解决方案。虽然 data-sort 能够达到目的,但是在数据表中 filter 无法正常工作。此外,如果您想将 "YYYYMMDD" 与 "HH MM" 进行排序,这也无济于事。我从 https://stackoverflow.com/questions/38079208/how-do-i-sort-by-a-hidden-column-in-datatables/38079753 找到了类似的解决方案,并尝试实现,这解决了任何格式日期排序的难题 - 例如:<td data-order={file.formatedPrintTime } >{this.formatDisplayDate(file.formatedPrintTime) }</td>。 - Maulik Kayastha
我尝试使用“yyyyMMdd”格式的data-order,它可以正常工作。例如:<td data-order="@item.SubscribeDate.ToString("yyyyMMdd")"> - uda
这不是一个可行的解决方案 - 这没有考虑到您的数据表中是否有多年的情况。 - TecHalo

6
如果您不想使用momentum.js或任何其他日期格式,则可以在日期值中添加毫秒级的日期格式,以便排序根据其毫秒数进行读取。并隐藏毫秒级的日期格式。 示例代码:
var date = new Date();
var millisecond = Date.parse(date);

HTML

<td>'<span style="display: none;">' + millisecond + "</span>" + date + </td>

就是这样。


3
你可以使用 PHP 解决这个问题。
$mydate = strtotime($startdate);
$newformat = date('d-m-Y',$mydate);
echo '<tr>';
echo '  <td data-sort="'. $mydate .'">'.$newformat .'</td>';

2
另一种解决方案: https://datatables.net/blog/2014-12-18 使用2个JavaScript库:
  1. cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js
  2. cdn.datatables.net/plug-ins/1.10.15/sorting/datetime-moment.js
然后只需这样:
$(document).ready(function() {
   $.fn.dataTable.moment( 'DD/MM/YYYY' );
   $('#example').DataTable(); 
});

2

虽然对于这个问题有很多答案,但我认为如果仅需要按照“YYYYMMDD”排序,则数据排序仅适用于此情况,并且在存在小时/分钟时不起作用。使用数据排序时,过滤器无法正常工作,至少我在尝试React JS时遇到了这个问题。

在我看来,最好的解决方案是使用data-order作为值,可以动态提供值以进行排序,并且在显示时格式可以不同。该解决方案稳健,适用于任何日期格式,包括“DD/MM/YYYY HH:M”。

例如:

<td data-order={obj.plainDateTime}>{this.formattedDisplayDate(obj.plainDateTime) }</td>

我从这里找到了解决方案-如何在DataTables中按隐藏列排序?


1
我尝试过这个方法,对我有效。

https://github.com/sedovsek/DataTables-EU-date-Plug-In

我使用了格式模式.ToString("dd/MM/yyyy");,然后在我的jQuery.Datatable中工作正常。
以下是jQ。
oTable = $('#grid').dataTable({
    "sPaginationType": "full_numbers",
    "aoColumns": [
        { "sType": "eu_date" },
        null
    ]
});
});

您应该像上面的代码一样使用sType定义具有日期的列。

1
请详细阐述它为什么有效,而不只是发布代码和链接。 - eddie_cat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接