jquery.tablesorter: Improve detection and handling of isoDate
authorDerk-Jan Hartman <hartman.wiki@gmail.com>
Sun, 9 Mar 2014 23:37:27 +0000 (00:37 +0100)
committerGergő Tisza <gtisza@wikimedia.org>
Thu, 24 Sep 2015 21:52:09 +0000 (21:52 +0000)
Bug: T54842
Change-Id: I193870dcc97477a4fd52a75d3beb9db21e64f171

resources/src/jquery/jquery.tablesorter.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.parsers.test.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js

index eaa138b..f6857e8 100644 (file)
                                new RegExp( /(https?|ftp|file):\/\// )
                        ],
                        isoDate: [
-                               new RegExp( /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/ )
+                               new RegExp( /^([-+]?\d{1,4})-([01]\d)-([0-3]\d)([T\s]((([01]\d|2[0-3])(:?[0-5]\d)?|24:?00)?(:?([0-5]\d))?([.,]\d+)?)([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?/ ),
+                               new RegExp( /^([-+]?\d{1,4})-([01]\d)-([0-3]\d)/ )
                        ],
                        usLongDate: [
                                new RegExp( /^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/ )
                        return ts.rgx.isoDate[ 0 ].test( s );
                },
                format: function ( s ) {
-                       return $.tablesorter.formatFloat( ( s !== '' ) ? new Date( s.replace(
-                       new RegExp( /-/g ), '/' ) ).getTime() : '0' );
+                       var isodate,
+                               matches;
+                       if ( !Date.prototype.toISOString ) {
+                               // Old browsers don't understand iso, Fallback to US date parsing and ignore the time part.
+                               matches = $.trim( s ).match( ts.rgx.isoDate[ 1 ] );
+                               if ( matches ) {
+                                       isodate = new Date( matches[ 2 ]  + '/' + matches[ 3 ] + '/' + matches[ 1 ] );
+                               } else {
+                                       return $.tablesorter.formatFloat( 0 );
+                               }
+                       } else {
+                               isodate = new Date( $.trim( s ) );
+                       }
+                       return $.tablesorter.formatFloat( ( isodate !== undefined ) ? isodate.getTime() : 0 );
                },
                type: 'numeric'
        } );
index 032551d..1726a48 100644 (file)
@@ -5,7 +5,7 @@
         */
 
        var text, ipv4,
-               simpleMDYDatesInMDY, simpleMDYDatesInDMY, oldMDYDates, complexMDYDates, clobberedDates, MYDates, YDates,
+               simpleMDYDatesInMDY, simpleMDYDatesInDMY, oldMDYDates, complexMDYDates, clobberedDates, MYDates, YDates, ISODates,
                currencyData, transformedCurrencyData;
 
        QUnit.module( 'jquery.tablesorter.parsers', QUnit.newMwEnvironment( {
        ];
        parserTest( 'Y Dates', 'date', YDates );
 
+       ISODates = [
+               [ '2000',               false, 946684800000, 'Plain 4-digit year' ],
+               [ '2000-01',            false, 946684800000, 'Year with month' ],
+               [ '2000-01-01', true, 946684800000, 'Year with month and day' ],
+               [ '2000-13-01', true, 0, 'Non existant month' ],
+               [ '2000-01-32', true, 0, 'Non existant day' ],
+               [ '2000-01-01T12:30:30',                true, 946729830000, 'Date with a time' ],
+               [ '2000-01-01T12:30:30Z',       true, 946729830000, 'Date with a UTC+0 time' ],
+               [ '2000-01-01T24:30:30Z',       true, 0, 'Date with invalid hours' ],
+               [ '2000-01-01T12:60:30Z',       true, 0, 'Date with invalid minutes' ],
+               [ '2000-01-01T12:30:61Z',       true, 0, 'Date with invalid amount of seconds' ],
+               [ '2000-01-01T23:59:59Z',       true, 946771199000, 'Edges of time' ],
+               [ '2000-01-01T12:30:30.111Z',   true, 946729830111, 'Date with milliseconds' ],
+               [ '2000-01-01T12:30:30.11111Z', true, 946729830111, 'Date with too high precision' ],
+               [ '2000-01-01T12:30:30,111Z',   true, 0, 'Date with milliseconds and , separator' ],
+               [ '2000-01-01T12:30:30+01:00',  true, 946726230000, 'Date time in UTC+1' ],
+               [ '2000-01-01T12:30:30+01:30',  true, 946724430000, 'Date time in UTC+1:30' ],
+               [ '2000-01-01T12:30:30-01:00',  true, 946733430000, 'Date time in UTC-1' ],
+               [ '2000-01-01T12:30:30-01:30',  true, 946735230000, 'Date time in UTC-1:30' ],
+               [ '2000-01-01T12:30:30.111+01:00', true, 946726230111, 'Date time and milliseconds in UTC+1 ' ]
+               /* Disable testcases, because behavior is browser dependant */
+               /*
+               [ '2000-11-31', true, 0, '31 days in 30 day month' ],
+               [ '50-01-01',   false, -60589296000000, 'Year with just two digits' ],
+               [ '-1000-01-01',        true, -93724128000000, 'Year BC' ],
+               [ '+1000-01-01',        true, -30610224000000, 'Date with +sign' ],
+               [ '2000-01-01 12:30:30Z',       true, 0, 'Date and time with no T marker' ],
+               [ '2000-01-01T12:30:60Z',       true, 946729860000, 'Date with leap second' ],
+               [ '2000-01-01T12:30:30-24:00',  true, 946816230000, 'Date time in UTC-24' ],
+               [ '2000-01-01T12:30:30+24:00',  true, 946643430000, 'Date time in UTC+24' ],
+               [ '2000-01-01T12:30:30+0100',   true, 946726230000, 'Time without separator in timezone offset' ]
+               */
+       ];
+       parserTest( 'ISO Dates', 'isoDate', ISODates );
+
        currencyData = [
                [ '1.02 $',     true, 1.02, '' ],
                [ '$ 3.00',     true, 3, '' ],
index d4d0ce1..8026cc3 100644 (file)
                        [ 'January 01 2010' ],
                        [ 'January 16 2010' ],
                        [ 'February 05 2010' ]
+               ],
+               isoDateSorting = [
+                       [ '2010-02-01' ],
+                       [ '2009-12-25T12:30:45.001Z' ],
+                       [ '2010-01-31' ],
+                       [ '2009' ],
+                       [ '2009-12-25T12:30:45' ],
+                       [ '2009-12-25T12:30:45.111' ],
+                       [ '2009-12-25T12:30:45+01:00' ]
+               ],
+               isoDateSortingSorted = [
+                       [ '2009' ],
+                       [ '2009-12-25T12:30:45' ],
+                       [ '2009-12-25T12:30:45+01:00' ],
+                       [ '2009-12-25T12:30:45.001Z' ],
+                       [ '2009-12-25T12:30:45.111' ],
+                       [ '2010-01-31' ],
+                       [ '2010-02-01' ]
                ];
 
        QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment( {
                }
        );
 
+       tableTest(
+               'ISO date sorting',
+               [ 'isoDate' ],
+               isoDateSorting,
+               isoDateSortingSorted,
+               function ( $table ) {
+                       mw.config.set( 'wgDefaultDateFormat', 'dmy' );
+
+                       $table.tablesorter();
+                       $table.find( '.headerSort:eq(0)' ).click();
+               }
+       );
+
        QUnit.test( 'Sorting images using alt text', 1, function ( assert ) {
                var $table = $(
                        '<table class="sortable">' +