Thursday 18th December, 2014

Ultimate date / time sorting plug-in

Date and time can be represented in almost limitless ways with different formats used to show a data point to end users. A long format such as "Thursday, 18th December 2014" might be used in cases where space is not constrained, but a more concise format might be "18/12/2014" or "12/18/2014" depending upon your location! Ambiguities such as this can lead to significant problems when attempting to order temporal data.

Questions about how to order temporal data correctly are a common feature in the forums, and in this post I'm going to introduce a new plug-in for DataTables that makes it possible to correctly order almost any date / time format using the excellent Moment.js library.

The need for a flexible solution

DataTables has a number of different data type detection and ordering methods built in, including currency, percentage values and dates. The date method uses the Date() object that is part of the Javascript specification to read date formatted data. This is done using Date.parse(), however the date formats supported by each browser vary significantly. Originally the Date specification didn't require that any specific format be supported (this has since changed in ECMAScript 5.1 to require ISO 8601), but all browser have converged on supporting ISO 8601, making it the only reliable format. Other formats are supported on a browser by browser basis.

The trouble with ISO 8061, despite it being unambiguous, is that it is rarely a format that you want to show to your end users. As a result, over the years, a number of plug-ins that sort particular date / time information have been written and contributed to the DataTables community by various authors (orthogonal data can also be used).

The downside to this is that for each slight change in format, you need to create a new plug-in. To resolve this, and to provide complete flexibility, we want the ability to specify the formats that DataTables will automatically detect and sort.

There are a number of libraries that are available to fill the deficiencies in Date() such as Sugar, Datejs and date.format, but for this example we will use Moment.js which provides a wide range of formatting options (any other library could also be used with the techniques presented in this post should you wish to use them!).

Operation

Using this "ultimate" date / time ordering plug-in for DataTables is as simple as including it (and Moment.js) on your page - which you can do using the DataTables CDN (or concatenate it into your other Javascript files for improved loading performance!):

JS
JS

Then, register the date / time format(s) that you wish DataTables to detect and order using the $.fn.dataTable.moment( format, locale ) method, which accepts up to two parameters:

  1. format - The date / time format to detect and order - the options available are defined in the Moment.js documentation.
  2. locale (optional) - Moment.js has extensive internationalisation support. This option can be optionally used to specify a locale.

Example

Consider the DataTable below which contains two date columns. One in the format HH:mm MMM D, YY and the other dddd, MMMM Do, YYYY (you wouldn't normally have two such disparate formats, but this is just for the example!). To create the DataTable we use the $.fn.dataTable.moment() function defined above and a standard DataTables creation:

$(document).ready(function() {
    $.fn.dataTable.moment( 'HH:mm MMM D, YY' );
    $.fn.dataTable.moment( 'dddd, MMMM Do, YYYY' );

    $('#example').DataTable();
} );
Name Company Created Updated
Dai Weeks Eu Foundation 11:10 Oct 18, 14 Sat, May 16th, 2015
Jade Dale Sit Amet Inc. 07:04 Apr 29, 14 Sat, July 25th, 2015
Melanie Buckner Tempus Lorem LLC 02:01 Jan 28, 15 Sun, October 11th, 2015
Cyrus Haney Phasellus Corp. 10:01 Jan 28, 14 Sat, December 28th, 2013
Melinda Salas Molestie Sed Id Limited 11:05 May 1, 14 Fri, May 15th, 2015
Rebecca Cline Eget Dictum Placerat Limited 02:12 Dec 20, 13 Wed, August 6th, 2014
India Lawson Eget Company 11:03 Mar 21, 15 Fri, July 11th, 2014
Elvis Whitfield Mollis Corporation 08:07 Jul 30, 15 Sat, February 28th, 2015
Castor Monroe Iaculis LLC 12:06 Jun 22, 14 Mon, June 2nd, 2014
Gareth Berry Malesuada Corp. 04:02 Feb 26, 14 Fri, February 27th, 2015
Anne Knox Neque Sed Consulting 04:04 Apr 11, 14 Sat, May 24th, 2014
Kasimir Martin Tortor Nunc Consulting 11:12 Dec 24, 14 Sat, July 25th, 2015
Drake Pugh Mattis Velit Industries 03:09 Sep 23, 15 Wed, March 5th, 2014
Carla Head Pretium Aliquet Institute 06:09 Sep 2, 15 Wed, January 8th, 2014
Shellie Henry Scelerisque Ltd 11:01 Jan 28, 15 Sun, February 1st, 2015
Patrick Koch Scelerisque Dui LLC 10:10 Oct 3, 14 Sun, May 17th, 2015
Dara Roberts Urna Convallis Erat Industries 11:08 Aug 13, 15 Sun, June 22nd, 2014
Yuli Wright Auctor Consulting 05:07 Jul 22, 14 Tue, March 25th, 2014
Cyrus Jensen Et Risus Associates 10:09 Sep 19, 15 Sat, May 16th, 2015
Holmes Talley Urna Nullam Lobortis Consulting 01:12 Dec 25, 14 Thu, February 13th, 2014
Iris Carver Laoreet Lectus Quis LLC 12:10 Oct 13, 14 Fri, November 7th, 2014
Leroy Cantrell In LLC 03:05 May 5, 15 Tue, June 2nd, 2015
Maggie Aguilar Mauris PC 02:12 Dec 7, 14 Thu, November 20th, 2014
Maggy Porter Mauris Blandit Ltd 11:06 Jun 4, 14 Tue, November 11th, 2014
Liberty Warner Ipsum Company 05:11 Nov 17, 15 Mon, October 5th, 2015
Raya Dean Felis Foundation 02:12 Dec 18, 14 Mon, February 10th, 2014
Jack Juarez Nunc Limited 01:09 Sep 7, 15 Mon, December 22nd, 2014
Nola King Varius Orci Incorporated 04:05 May 12, 15 Tue, June 24th, 2014
Carlos Holman Odio LLC 01:08 Aug 16, 15 Thu, August 20th, 2015
Aquila Finch Egestas Ligula Nullam Institute 12:09 Sep 3, 15 Sat, March 22nd, 2014
Seth Porter Sem Ut Inc. 01:06 Jun 4, 15 Sun, March 1st, 2015
Oleg Mcpherson Nunc Ac Sem LLP 03:08 Aug 3, 14 Sun, September 21st, 2014
Kennan Snyder Amet Consectetuer Associates 06:01 Jan 23, 14 Mon, April 7th, 2014
Emery Donovan Dapibus Inc. 08:06 Jun 14, 14 Tue, September 30th, 2014
Naida Hunter Augue Scelerisque Mollis Inc. 11:12 Dec 23, 13 Sun, July 19th, 2015
Clinton Morrison Non Lacinia Industries 02:03 Mar 18, 14 Fri, March 6th, 2015
Helen Gutierrez Faucibus Incorporated 07:08 Aug 7, 15 Tue, February 4th, 2014
Candice Bonner Donec LLP 05:12 Dec 28, 13 Mon, March 16th, 2015
Nissim Carter Suspendisse Sed Limited 01:03 Mar 19, 14 Mon, June 29th, 2015
Kasimir Hoffman Id Libero Donec Consulting 05:12 Dec 23, 14 Wed, September 23rd, 2015
Imogene Mcconnell Vitae Associates 07:02 Feb 17, 15 Tue, July 22nd, 2014
Sage Mosley Metus In Inc. 05:05 May 24, 15 Mon, April 21st, 2014
Sybil Puckett Vel Lectus LLP 09:06 Jun 9, 14 Sat, September 6th, 2014
Kylynn Solis Ac Limited 10:01 Jan 20, 15 Tue, September 15th, 2015
Beatrice Hurley Mauris A Nunc Corporation 04:05 May 11, 14 Sun, April 26th, 2015
Troy Marquez Dapibus Quam Institute 12:02 Feb 7, 15 Thu, April 23rd, 2015
Malcolm Payne Adipiscing Ligula Institute 04:08 Aug 17, 15 Tue, September 2nd, 2014
Wade Valenzuela Sagittis Duis Gravida Corporation 03:05 May 22, 14 Mon, January 13th, 2014
Kathleen Gilmore Urna Nec Ltd 05:03 Mar 5, 14 Mon, November 16th, 2015
Maite Scott Ipsum Cursus Inc. 01:05 May 28, 14 Sun, June 8th, 2014
Kamal Nash Sem Vitae Company 05:10 Oct 7, 14 Thu, June 26th, 2014
Iliana West Ac Eleifend Limited 01:10 Oct 24, 15 Wed, July 2nd, 2014
Susan Osborn Sollicitudin Adipiscing Ligula Institute 03:02 Feb 18, 14 Sat, June 13th, 2015
Adena Carter Nibh Industries 04:01 Jan 27, 15 Tue, February 3rd, 2015
Duncan Mckinney Vel Convallis In Inc. 09:11 Nov 23, 15 Sat, December 12th, 2015
Ariana Whitehead Fermentum Metus Associates 03:06 Jun 9, 14 Tue, December 15th, 2015
Fiona Henderson Eget Tincidunt Dui Inc. 03:01 Jan 1, 14 Fri, January 9th, 2015
Judah Gates Donec Felis Associates 04:11 Nov 30, 15 Mon, September 28th, 2015
Hasad Mccarthy Ac Tellus Company 12:01 Jan 21, 14 Mon, January 27th, 2014
Shay Valencia Natoque Associates 05:03 Mar 4, 14 Mon, December 15th, 2014
Hillary Tran Integer Mollis Foundation 08:12 Dec 31, 14 Wed, August 26th, 2015
Margaret Sellers Lacus Quisque Corporation 11:10 Oct 17, 15 Sun, July 5th, 2015
Prescott Morton Vestibulum Associates 01:04 Apr 27, 15 Sun, June 14th, 2015
Charity Gilbert Tortor At Risus Associates 01:07 Jul 31, 14 Thu, December 18th, 2014
Freya Randolph Ut Institute 07:11 Nov 3, 15 Sat, September 27th, 2014
Nita Howe Ornare Fusce Inc. 11:02 Feb 12, 14 Tue, June 9th, 2015
Kirby Whitney Faucibus Morbi Vehicula Foundation 11:12 Dec 22, 13 Wed, August 26th, 2015
Amos Jarvis Mauris Suspendisse Aliquet LLP 01:05 May 10, 15 Mon, July 14th, 2014
Kim Hunter Ligula Donec Luctus Corp. 07:11 Nov 25, 15 Thu, October 23rd, 2014
Rosalyn Benton Iaculis Quis Pede Corp. 02:09 Sep 16, 14 Sun, November 15th, 2015
Anjolie Floyd Nunc Corp. 12:03 Mar 28, 14 Mon, December 1st, 2014
Basil Harmon Semper Rutrum Fusce PC 05:12 Dec 9, 15 Wed, September 17th, 2014
Kermit Herrera Sed Tortor Integer Limited 03:09 Sep 26, 14 Sun, June 14th, 2015
Winifred Pearson Augue Industries 10:09 Sep 18, 15 Tue, August 4th, 2015
Lester Fischer Aenean PC 02:09 Sep 15, 15 Wed, July 29th, 2015
Tatum Daugherty Nunc Nulla LLP 09:06 Jun 25, 15 Wed, February 19th, 2014
Zachary Wilder Nec LLC 03:09 Sep 19, 14 Wed, April 8th, 2015
Laith Peters Ipsum Leo Elementum Institute 11:06 Jun 17, 14 Thu, November 13th, 2014
Evelyn Ramos Nunc Industries 01:06 Jun 3, 14 Thu, April 10th, 2014
Mara Michael Ut Aliquam LLC 10:07 Jul 14, 14 Thu, November 26th, 2015
Jemima Powers Eu Arcu Morbi LLP 06:08 Aug 4, 14 Fri, May 1st, 2015
Tanek Guthrie Sit Associates 09:02 Feb 19, 15 Thu, May 28th, 2015
Harriet Crane Quis Accumsan Ltd 12:08 Aug 2, 14 Sun, December 13th, 2015
Jin Bond Auctor Quis Corp. 09:08 Aug 25, 15 Tue, November 18th, 2014
Ursa Jacobs Convallis Ante PC 08:04 Apr 5, 14 Tue, February 18th, 2014
Jason Collier Vel Pede Blandit Ltd 01:05 May 12, 14 Mon, September 21st, 2015
Quemby Stone Lacus Quisque Incorporated 09:08 Aug 10, 15 Thu, July 2nd, 2015
Melvin Sweet Nec Foundation 05:01 Jan 17, 15 Thu, May 22nd, 2014
Thor Wilson Arcu Vivamus Sit Industries 02:02 Feb 17, 15 Thu, August 7th, 2014
Burton Marquez Augue Corporation 09:12 Dec 2, 15 Wed, November 26th, 2014
Kai Ware Facilisis Vitae Limited 12:06 Jun 23, 14 Sun, June 29th, 2014
Holmes Murphy Dui Nec Tempus Inc. 12:10 Oct 25, 15 Sun, April 26th, 2015
Blaine Valentine Proin Institute 04:10 Oct 16, 14 Mon, March 30th, 2015
Lionel Pacheco Dolor Company 07:03 Mar 18, 14 Sat, May 24th, 2014
Keefe Fletcher A Mi Fringilla Industries 03:09 Sep 25, 15 Thu, October 22nd, 2015
Slade Rojas Sodales Nisi Magna PC 08:09 Sep 1, 15 Wed, June 11th, 2014
Vanna Kirkland Tempus Inc. 03:02 Feb 14, 15 Wed, December 9th, 2015
Cameron Peters Lobortis Tellus Justo Limited 06:02 Feb 9, 15 Fri, January 2nd, 2015
Reed Freeman Augue Sed Molestie LLP 01:09 Sep 24, 15 Sun, July 19th, 2015
Florence Burgess Aliquam Auctor Velit Incorporated 05:04 Apr 20, 14 Mon, September 8th, 2014

How it works

The actual plug-in code is very simple - just 15 lines. All of the real "magic" is done for us by Moment.js. However, we do need to know how to create plug-ins for DataTables to hook it together.

Automatic type detection plug-in

DataTables' type detection methods are attached to the $.fn.dataTable.ext.type.detect array. This is an array of functions that DataTables will loop over, checking to see if the data in a column matches any of the given types.

So in this case we can simply use the moment().isValid() method to check to see if the data passed into the function is valid or not. The result is:

$.fn.dataTable.ext.type.detect.unshift( function ( d ) {
    return moment( d, format, locale, true ).isValid() ?
        'moment-'+format :
        null;
} );

Note that unshift is used to prefix the type detection function to the start of the array to ensure that DataTables uses this type detection before any others.

Ordering plug-in

Similar to the type detection plug-in, the ordering plug-in is attached to the $.fn.dataTable.ext.type.order object, using the name of the type that the ordering method will apply to. DataTables has built in ordering comparison for numeric and string values, so all we need to do is create a plug-in that will return a deformatted numeric representation of the date / time, for which we can use moment().unix():

$.fn.dataTable.ext.type.order[ 'moment-'+format+'-pre' ] = function ( d ) {
    return moment( d, format, locale, true ).unix();
};

Completed plug-in

Putting it all together we have the resulting plug-in for DataTables - the ultimate date / time ordering plug-in, thanks to Moment.js!

$.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();
    };
};