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


78

我正在使用一个名为datatables的Jquery插件

太棒了,但是我无法根据dd / mm / yyyy格式正确地对日期进行排序。

我已经看过他们的支持格式,但是这些修复程序似乎都不起作用。

有人可以帮我吗?



我看过了,但不明白如何将其应用于日期。我已经用正斜杠代替了破折号,但对于其余的内容还不确定。它说它检查小数点后一位,您将如何检查两个破折号?
jaget 2012年

您没有提到加载数据的方法,因此我向混合添加了AJAX解决方案。我发现我的大多数表都是从浏览器中的数据开始的,但最终还是全部迁移到了AJAX。
Sablefoste

Answers:


135

更新2020:HTML解决方案

由于HTML 5的开发水平很高,几乎所有主流浏览器都支持它。因此,现在更干净的方法是使用HTML5数据属性 (maxx777提供了我正在使用简单HTML的PHP​​解决方案)。对于我们场景中的非数字数据,我们可以使用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));
}
} );
 

将上述代码添加到脚本中,并将带有Date值的特定列设置为 { "sType": "date-uk" },其他设置为null,如下所示:

$(document).ready(function() {
    $('#example').dataTable( {
        "aoColumns": [
            null,
            null,
            null,
            null,
            { "sType": "date-uk" },
            null
        ]
    });
    });

1
您比我更快地得到正确答案。我本来打算使用live.datatables.net/abarot/edit#javascript,html,但是您的代码要好得多,而且制作时间更少。非常感谢您的帮助。仍然不确定较小的功能如何使用,但至少我知道它们如何工作。非常感谢您的帮助。
jaget 2012年

1
我不知道我想念的是什么,但这无法正确地对日期进行排序,即使在已编辑的链接中也是如此。
2014年

1
@Fede实际上帖子中的链接是/edit最近更新的链接,我已更正了该链接。请注意,它只排序dd / mm / yyyy格式的日期。
Zaheer Ahmed 2015年

2
如果要将日期排序为字符串而不是数字,则必须在“ date-uk-pre”函数的末尾删除“ * 1”,该函数将返回的日期转换为数字。有了这个变化,玩起来就像魅力!:)
尼基·沃图

1
这是一个
很好的

93

日期排序-具有隐藏元素

将日期转换为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; 
}

3
除此以外,OMG没有任何作用。如果使用rails,这应该是您需要的代码(idea只是我使用的型号名称):<td> <span> <%= idea.created_at.strftime("%Y%m%d") %> </span> <%= idea.created_at.strftime("%d/%m/%Y") %> </td>
matias salgado

7
不幸的是,当您使用datatables导出pdf插件时,它会占用您所有的HTML标签(包括hideenHTML标签)。结果是导出的文件中的数据重复。它导出里面的数据<span>
Are0215

@AnulalS对不起,我离开了键盘,只是看到了您的评论。这是一个很旧的帖子,我已经更新了答案。感谢您指出更正。
Zaheer Ahmed

@ Are0215,您可以自定义生成的内容,以从span:按钮中删除重复数据:[{扩展:'pdfHtml5',customize:函数(doc){doc.content [0] .table.body.forEach(function(row ){row [5] .text = row [5] .text.split('</ span>')。pop();});}}
Alexis Delahaye

它对我有用,但我不理解其背后的逻辑。你可以解释吗 ?
David Coder

36

我知道这是一个古老的问题,答案也很古老。最近,我遇到了一种简单而干净的日期排序方式。可以通过HTML5data-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
可以在以下位置找到此功能的文档:datatables.net/release-datatables/examples/advanced_init/…–
mitchdav

9

试试这个插件。

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

例:

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

如果有时间怎么办?
伊莱(Eli)2016年

@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

7

这样,它为我工作。

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

data-order属性中的此日期格式应采用DataTable支持的这种格式。


1
我认为这应该被视为正确的解决方案。虽然数据排序可达到目的,但fitler在数据表中无法正常工作。如果要用“ HH MM”对“ YYYYMMDD”进行排序,这也无济于事。我从-stackoverflow.com/questions/38079208/…找到了类似的解决方案,并尝试了实现,它解决了对任何格式的日期进行排序的难题-例如:<td data-order = {file.formatedPrintTime}> {this.formatDisplayDate( file.formatedPrintTime)} </ td>
Maulik Kayastha

4

如果您不想使用动量.js或任何其他日期格式,则可以在日期值中添加以毫秒为单位的日期格式,以便按毫秒进行排序。并隐藏毫秒日期格式。

样例代码:

var date = new Date();
var millisecond = Date.parse(date);

的HTML

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

而已。


2

您可以使用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(); 
});

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 2014年

1

在php或js中,只需传递一个数组并使用正交,例如:

$var[0][0] = "like as u wish, 30/12/2015 or something else";
$var[0][1] = strtotime($your_date_variable);

并且,在数据表中...

$('#data-table-contas_pagar').dataTable({
    "columnDefs": [
        {"targets":[0],"data": [0],"render": {"_": [0],"sort": [1]}}
    ]
});

1

尽管问题的答案很多,但我认为只有在“ YYYYMMDD”中需要排序时,数据排序才有效,而在“小时/分钟”的情况下则无效。使用数据排序时,过滤器无法正常工作,至少我在React JS中尝试时遇到了这个问题。

我认为最好的解决方案是使用数据顺序,因为可以动态提供值以进行排序,并且显示时格式可以不同。该解决方案功能强大,可用于任何日期格式,包括“ DD / MM / YYYY HH:M”。

例如:

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

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


0

如果您必须处理英国格式的日期,Zaheer Ahmed的解决方案效果很好。

我对此解决方案有疑问,因为我必须管理美国格式的日期。

我想出了这个小小的变化:

function parseDate(a) {
    var ukDatea = a.split('/');
    return (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
}

jQuery.extend( jQuery.fn.dataTableExt.oSort, {
    "date-uk-pre": function ( a ) {
        return parseDate(a);
    },

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

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

后跟您的“ aoColumns”定义。


我应该在哪里调用parseDate?
BurakKarakuş2014年

0

这种解决方案是完全错误的。您不能仅将日期的每个组成部分相加就将日期转换为数字。例如,如果您使用以下日期尝试该逻辑,则将发现它与之不正确匹配:

20/01/2014 = 2035 15/02/2014 = 2031

女巫的日期排在第一,升序?1月20日?不按照这个逻辑:P

执行parsedate方法的正确方法是将字符串转换为有效的日期时间,并且它们使用getTime函数对表进行正确排序。

var day = a.split('/')[0]
var month = a.split('/')[1]
var year = a.split('/')[2]

var date = new Date(month + "/" + day + "/" + year)
return date.getTime()

0

我想指出的是,通过Ajax使用来自服务器的数据时,解决方案非常简单,但可能不会立即显而易见。

返回排序顺序数组时,数据表将发送(在中$_POST)一个2元素数组,该数组等效于:

$_POST['order'][0] =array('column'=>'SortColumnName', 'dir'=>'asc'); 
// 2nd element is either 'asc' or 'desc'

因此,您可以使用所需的任何格式显示日期。只是让您的服务器仅根据sortColumnName

例如,在PHP(与MySQL)中,我使用以下代码:

 if (isset($_POST['order'])) {
          switch ($_POST['order'][0]['column']) {
               case 0:// sort by Primary Key
                    $order = 'pkItemid';
                    break;
               case 1:// Sort by reference number
                    $order = 'refNo';
                    break;
               case 2://Date Started
                    $order = 'dOpen';
                    break;
               default :
                    $order = 'pkItemid';
          }
          $orderdir = ($_POST['order'][0]['dir'] === 'desc') ? 'desc' : 'asc';
     }

请注意,由于的任何内容都不会$_POST传递给$order$orderdir,因此不可能进行跨脚本攻击。

现在,只需附加一个MySQL查询:

$sql ="SELECT pkItemid, refNo, DATE_FORMAT(dOpen,'%b %e, %Y') AS dateStarted
       FROM tblReference 
       ORDER BY $order $orderdir;";

运行查询,然后仅将dateStarted值返回给json中的Datatables。


应该注意的是,必须启用服务器端处理才能使其正常工作。
Apps-n-Add-Ons

0

使用此代码段!

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

    // Add type detection
    types.detect.unshift( function ( d ) {
        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 ) {
        return moment( d, format, locale, true ).unix();
    };
};

$.fn.dataTable.moment('DD/MM/YYYY');

$('#example').DataTable();
});

当js适用于所有日期和时间格式时,像我之前所做的那样,在初始化数据表之前添加此snipper。

还记得加载http://momentjs.com/


0

我也有同样的问题。

我在td中使用span与之类似,如03/21/2017,通过这样做,数据表将此视为字符串并且排序不起作用。

我删除了td内的span,并进行了修复。喜欢,03/21/2017


0

我在其余电话中使用过

**日期变量为:已创建**

var call = $.ajax({
            url: "../_api/Web/Lists/GetByTitle('NewUser')/items?$filter=(Created%20ge%20datetime'"+FromDate+"')%20and%20(Created%20le%20datetime'"+ToDate+"' and Title eq '"+epf+"' )&$top=5000",
            type: "GET",
            dataType: "json",
            headers: {
                Accept: "application/json;odata=verbose"
            }

            });

  call.done(function (data,textStatus, jqXHR){
        $('#example').dataTable({
            "bDestroy": true,
            "bProcessing": true,
            "aaData": data.d.results,
            "aLengthMenu" : [
             [50,100],
             [50,100]
            ],
             dom: 'Bfrtip',
            buttons: [
                'copy', 'csv', 'excel'
            ],

            "aoColumnDefs": [{ "bVisible": false  }],
            "aoColumns": [
                { "mData": "ID" },
                { "mData": "Title" },
                { "mData": "EmployeeName" },
                { "mData": "Department1" },
                { "mData": "ServicingAt" },
                { "mData": "TestField" }, 
                { "mData": "BranchCode" },   
                { "mData": "Created" ,"render": function (data, type, row) {
        data = moment(data).format('DD MMM YYYY');
        return data;
    }

0

解决这个问题的最简单方法

只需像这样修改您的设计

//Add this data order attribute to td
<td data-order="@item.CreatedOn.ToUnixTimeStamp()">
                                    @item.CreatedOn
                                </td>
                                
                                
               
               Add create this Date Time helper function
// #region Region 
 public static long ToUnixTimeStamp(this DateTime dateTime) {
 TimeSpan timeSpan = (dateTime - new DateTime(1970, 1, 1, 0, 0, 0));
     return (long)timeSpan.TotalSeconds;
     } 
     #endregion


0

似乎对我有用的是

在数据集中将通过选择查询从我的数据库中获取的完整日期时间对象推送到数据表格式中,将以数据表格式“ 2018-01-05 08:45:56”绘制

然后

    $('#Table').DataTable({
        data: dataset,
        deferRender: 200,
        destroy: true,
        scrollY: false,
        scrollCollapse: true,
        scroller: true,
        "order": [[2, "desc"]],
        'columnDefs': [
            {
                'targets': 2,
                'createdCell':  function (td, cellData, rowData, row, col) {                        
                    var datestamp = new Date(cellData);
                    $(td).html(datestamp.getUTCDate() + '-' + (datestamp.getMonth()+1) + '-' + datestamp.getFullYear());
                }
            }
        ],
        "initComplete": function(settings, json) {
            $($.fn.dataTable.tables(true)).DataTable()
                .columns.adjust();               
        }
    });

行正确排序,然后在行中获取所需的html


0

正如我发现的,在这种情况下最简单的排序方法是在JS中添加“ aaSorting”选项。

例如:

$(document).ready(function() {
    $('#contacts-table').dataTable({
        "aaSorting": [0, 'desc']
});

这里的问题是此示例将对第1列中的条目(如STRING)进行排序,但不对日期进行排序。如果源代码允许您将日期格式从dd / mm / yyyy更改为yyyy / mm / dd,则“ aaSorting”将为您正常工作。


0

像这样使用标记data-order上的属性<td>Ruby示例):

    <td data order='<%=rentroll.decorate.date%>'><%=rentroll.decorate.date%></td>

您的装饰器功能如下:

    def date
    object.date&.strftime("%d/%m/%Y")
    end

0

如果您从数据库中获取日期并为每行执行一个for循环,然后将其附加到字符串以在javascript中使用以自动填充数据表,则它将需要如下所示。请注意,在使用隐藏的跨度技巧时,您需要考虑日期的个位数,例如第6小时,则需要在日期前加上一个零,否则跨度技巧在排序中不起作用。代码:

 DateTime getDate2 = Convert.ToDateTime(row["date"]);
 var hour = getDate2.Hour.ToString();
 if (hour.Length == 1)
 {
 hour = "0" + hour;
 }
 var minutes = getDate2.Minute.ToString();
 if (minutes.Length == 1)
 {
 minutes = "0" + minutes;
 }
 var year = getDate2.Year.ToString();
 var month = getDate2.Month.ToString();
 if (month.Length == 1)
 {
 month = "0" + month;
 }
 var day = getDate2.Day.ToString();
 if (day.Length == 1)
 {
 day = "0" + day;
 }
 var dateForSorting = year + month + day + hour + minutes; 
 dataFromDatabase.Append("<span style=\u0022display:none;\u0022>" + dateForSorting +
 </span>");


0

对于要排序的列,请保留“ sType”:“ date-uk”,例如:-"data": "OrderDate", "sType": "date-uk" 在ajax中完成Datatable脚本后,保留以下代码

 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));
            }
        });

然后您将以这种格式获取日期为22-10-2018


您的答案有何特别之处??
tod

特殊意义上的??我以为上面的评论不是那么简短,所以我只是保持简短。在我的机器上测试该代码后,我发布了这个答案
vidya 18-10-23

0

问题源是日期时间格式。

错误的样本:“ MM-dd-yyyy H:mm”,“ MM-dd-yyyy”

正确的样本:“ MM-dd-yyyy HH:mm”


0

最简单的方法是在该列的每个TD标签中的日期之前添加一个隐藏的时间戳,例如:

<td class="sorting_1">
    <span class="d-none">1547022615</span>09/01/2019  09:30
</td>

使用默认的字符串排序,时间戳将按所需的方式对列进行排序,并且在浏览器中呈现时不会显示。


0

任何使用UTC格式或其他格式的人都可以阅读

假设您的日期采用这种格式

2019年10月15日星期二08:41:35 GMT + 0000(UTC)

首先,我们可以使用矩将其转换为毫秒

例如,在我的情况下,我使用的是HandleBar.js。所以我创建了一个Helper函数来简化它

hbs.registerHelper('dateformat', function (datetime) {
return moment(datetime).valueOf(); })

要不然

只是这样转换

moment("Tue Oct 15 2019 08:41:35 GMT+0000 (UTC)").valueOf();

一旦完成,只需将这些值传递到表中

现在,这里的技巧是将它们都传递给它们,并以毫秒为单位隐藏一个并以UTC格式显示一个

<td >
<span class="hideThisDate">{{DATA IN MILLISECONDS}}</span> 
{{YOUR DATE IN NORMAL FORMAT}}</td>

现在只需简单地通过CSS隐藏毫秒

.hideThisDate {
 display:none;
 }

而且您应该很好走!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.