有没有一种方法可以为IE调整“dd-MON-yyyy”日期格式?

7
我支持的组织规定所有日期都以dd-MON-yyyy格式显示(例如10-SEP-2006,08-MAY-2013)。请参见示例数据集http://jsfiddle.net/jhfrench/zpWWa/
当在Chrome上运行时,dataTables正确地将此模式识别为日期。但是,在IE7上运行时,dataTables(或IE?)无法将此模式识别为日期。不幸的是,我们必须支持IE7是否有一种方法可以为IE添加“dd-MON-yyyy”格式,而不会影响Chrome或其他本地支持该格式的浏览器呢? 我正在使用IE条件来指定HTML标签,因此我可以根据<HTML class="lt-ie9">进行关键操作;对于此页面,我还在使用Modernizr(如果有相关测试)。

IE会识别没有连字符的格式。它们是否也是必需的? - Kevin Boucher
1
这个问题看起来与此问题非常相似。你试过这种方法吗?顺便说一句,在像日本这样使用月份数字而不是名称的文化中,dd-MON-yyyy仍然是不明确的。 - explunit
这是一个类似的问题,但那个解决方案会引入问题,因为我必须预先定义哪些列是日期。 - Jeromy French
2个回答

4

与其试图为IE7添加shim,我认为最简单的解决方案是编写自己的排序函数,并在使用日期格式的所有列中调用它。这在DataTables中非常容易实现,步骤如下:

http://www.datatables.net/plug-ins/sorting

您可以手动定义表格以使用新的排序算法来对列进行排序,但这有点笨拙,因为您需要在使用该格式的每个地方都这样做。相反,您可以自动检测,如下所述:

http://www.datatables.net/plug-ins/type-detection

我为您创建了一份与您的fiddle分支相似的快速解决方案 - 我只是将日期转换为简单数字 - 只要您信任数据,这应该是没问题的。否则,您可能需要将其转换为实际的日期对象,这可能是更加强大的方法。

http://jsfiddle.net/pFdyK/

代码:

// Put these somewhere better than a global :)
var months = "JAN_FEB_MAR_APR_MAY_JUN_JUL_AUG_SEP_OCT_NOV_DEC".split("_");
function monthToOrd(month) {
    return $.inArray(month, months);
}
function customDateToOrd(date) {
    // Convert to a number YYYYMMDD which we can use to order
    var dateParts = date.split(/-/);
    var day = dateParts[0];
    var month = monthToOrd(dateParts[1]);
    var year = dateParts[2];
    var numericDate = (year * 10000) + (month * 100) + day;
    return numericDate;
}

// This will help DataTables magic detect your custom format
// Unshift so that it's the first data type (overridding in built ones)
jQuery.fn.dataTableExt.aTypes.unshift(
    function ( sData )
    {
        // You might want to make this check a little tighter so you don't match
        // invalid dates, but this should do for now
        if (sData.match(/\d{2}-[A-Za-z]{3}-\d{4}/))
            return 'custom-date';
        else
            return null;
    }
);

// define the sorts
jQuery.fn.dataTableExt.oSort['custom-date-asc']  = function(a,b) {
    var ordA = customDateToOrd(a);
    var ordB = customDateToOrd(b);
    return (ordA < ordB) ? -1 : ((ordA > ordB) ? 1 : 0);
};

jQuery.fn.dataTableExt.oSort['custom-date-desc'] = function(a,b) {
    var ordA = customDateToOrd(a);
    var ordB = customDateToOrd(b);
    return (ordA < ordB) ? 1 : ((ordA > ordB) ? -1 : 0);
};

$(document).ready(function() {
    $('html').addClass('lt-ie9');
   $('table.datatable').dataTable();
} );

NB代码假设日期格式中的大写等情况,但你应该能理解这个概念。 - Shaun McCarthy

0

Shaun的精彩回答的基础上,至少有两种方法可以测试是否需要为dd-MMM-yyyy格式进行shim。在与JSLint(我发誓它讨厌我写的每一行ECMA代码)进行深入磋商后,我修改了Shaun的代码。

使用IE条件语句

如果您已经使用IE条件语句(<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->),那么您只需测试HTML.lt-ie9并有条件地定义新的排序算法,然后调用dataTables即可:

//test for html.lt-ie9
if ($('html.lt-ie9').length) {
    //create the new magic sorting
    var customDateDDMMMYYYYToOrd = function (date) {
        "use strict"; //let's avoid tom-foolery in this function
        // Convert to a number YYYYMMDD which we can use to order
        var dateParts = date.split(/-/);
        return (dateParts[2] * 10000) + ($.inArray(dateParts[1].toUpperCase(), ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"]) * 100) + dateParts[0];
    };

    // This will help DataTables magic detect the "dd-MMM-yyyy" format; Unshift so that it's the first data type (so it takes priority over existing)
    jQuery.fn.dataTableExt.aTypes.unshift(
        function (sData) {
            "use strict"; //let's avoid tom-foolery in this function
            if (/^([0-2]?\d|3[0-1])-(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)-\d{4}/i.test(sData)) {
                return 'custom-date-dd-mmm-yyyy';
            }
            return null;
        }
    );

    // define the sorts
    jQuery.fn.dataTableExt.oSort['custom-date-dd-mmm-yyyy-asc'] = function (a, b) {
        "use strict"; //let's avoid tom-foolery in this function
        var ordA = customDateDDMMMYYYYToOrd(a),
            ordB = customDateDDMMMYYYYToOrd(b);
        return (ordA < ordB) ? -1 : ((ordA > ordB) ? 1 : 0);
    };

    jQuery.fn.dataTableExt.oSort['custom-date-dd-mmm-yyyy-desc'] = function (a, b) {
        "use strict"; //let's avoid tom-foolery in this function
        var ordA = customDateDDMMMYYYYToOrd(a),
            ordB = customDateDDMMMYYYYToOrd(b);
        return (ordA < ordB) ? 1 : ((ordA > ordB) ? -1 : 0);
    };
};

//now call the dataTable plugin against the target tables (in this case, any table with `class="dataTable"`)
$('table.datatable').dataTable();

请查看在http://jsfiddle.net/jhfrench/nEsCt/的IE条件示例

使用Modernizr进行测试

另一方面,如果你倾向于使用Modernizr来测试能力,我们可以定义Modernizr测试,然后使用Modernizr执行测试并有条件地加载shim魔法(从.js文件),然后调用dataTables:

//define the Modernizr test
Modernizr.addTest('valid_date_dd_mmm_yyyy', function() {
    return !isNaN(Date.parse("17-MAY-2013"));
});

//if Modernizr determines "dd-mmm-yyyy" dates are not supported, load the following JavaScript resources
Modernizr.load([
    {
        test: Modernizr.valid_date_dd_mmm_yyyy,
        nope: 'http://appliedinter.net/Workstream/common_files/js/dataTable_shim_dd-MMM-yyyy.js',
        complete: function () {
            $(document).ready(function () {
                //now call the dataTable plugin against the target tables (in this case, any table with `class="dataTable"`)
                $('table.datatable').dataTable();
            });
        }
    }
]);

请查看Modernizr方法,网址http://jsfiddle.net/jhfrench/tNkGC/


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