From 2891978fd15297a05aa4f11b02579a16cdef182d Mon Sep 17 00:00:00 2001 From: Allan Jardine Date: Sun, 5 Jan 2014 11:18:42 +0000 Subject: [PATCH] Fix: Numbers incorrectly detected as dates in Chrome - Chrome (V8) will incorrectly detect '$245.12' and similar as dates, since V8 will strip unknown characters from a string given to Date.parse and then attempt to parse the rest of the string - in the example above: Dec, 245: https://code.google.com/p/v8/source/browse/trunk/src/dateparser-inl.h#72 - The fix implemented to to check for a leading a-zA-Z, number or +-. Although this isn't a perfect match for what Chrome does, it, I think, a good enough effort to chatch nearly all particular use cases. - Additionaly, V8 will try to parse a single number passed into Date.parse - 1-12 are months, 32+ are years. As such, the numeric type detection much be a highter priority than the date detection, since Chrome might incorrectly use a column as a date. It would sort correctly, but it isn't "correct". - The take away from this is that Date.parse cannot be used for date format validation on its own... --- .datatables-commit-sync | 2 +- media/js/jquery.dataTables.js | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.datatables-commit-sync b/.datatables-commit-sync index 013aa61e..cc76d89f 100644 --- a/.datatables-commit-sync +++ b/.datatables-commit-sync @@ -1 +1 @@ -64efe2489b245104ead81e891eddce0d0127d84e +5fd86f5bbcd9e59c4760202d55e4f5e33bd0f8ed diff --git a/media/js/jquery.dataTables.js b/media/js/jquery.dataTables.js index d5960032..9e3dc41d 100644 --- a/media/js/jquery.dataTables.js +++ b/media/js/jquery.dataTables.js @@ -104,6 +104,7 @@ var _re_new_lines = /[\r\n]/g; var _re_html = /<.*?>/g; var _re_formatted_numeric = /[',$£€¥%]/g; + var _re_date_start = /^[\d\+\-a-zA-Z]/; @@ -13692,19 +13693,26 @@ // Built in type detection. See model.ext.aTypes for information about // what is required from this methods. $.extend( DataTable.ext.type.detect, [ - // Dates (only those recognised by the browser's Date.parse) - function ( d ) - { - var parsed = Date.parse(d); - return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null; - }, - - // Plain numbers + // Plain numbers - first since V8 detects some plain numbers as dates + // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...). function ( d ) { return _isNumber( d ) ? 'numeric' : null; }, + // Dates (only those recognised by the browser's Date.parse) + function ( d ) + { + // V8 will remove any unknown characters at the start of the expression, + // leading to false matches such as `$245.12` being a valid date. See + // forum thread 18941 for detail. + if ( d && ! _re_date_start.test(d) ) { + return null; + } + var parsed = Date.parse(d); + return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null; + }, + // Formatted numbers function ( d ) {