无效日期不会在IE中返回为无效日期

时间:2018-08-16 16:59:13

标签: javascript date internet-explorer

我正在使用浏览器日期功能。我输入的内容类似13/77/7777,这是无效的日期。我喜欢

new Date('13/77/7777').getTime();

这将返回FF和chrome中的NAN,但在IE中会返回一个数字。我该如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

我在IE11中通过.getTime()获得的值为183289406400000
日期本身返回为March 18, 7778

这是因为,令人发疯的是,IE11正在以13/77/7777格式解析mm/dd/yyyy,并得出了“ 7777年13月和77日”的结果(令人沮丧且令人惊讶的是)算出March 18, 7778(如果您将January 1, 7777添加13个月零77天)。

鉴于快速的Google搜索没有发现IE11中Date构造函数的任何polyfill的结果,我怀疑最合理的解决方法是在尝试使用构造函数解析日期之前对字符串进行完整性检查

需要警告的是,虽然它可能没有达到的效率(或准确度),但它应作为帮助您入门的合理示例。这样的事情应该做:

function isValidDateString(s) {
    "use strict";

    if (typeof s !== "string") {
        return false; // not a string, exit.
    }

    var parts = s.split("/");

    if (parts.length !== 3) {
        return false; // unexpected number of slashes. exit.
    }

    var d31 = [1, 3, 5, 7, 8, 10, 12];
    var d30 = [4, 6, 9, 11];

    var mm = parseInt(parts[0]);
    var dd = parseInt(parts[1]);
    var yyyy = parseInt(parts[2]);

    // empirical testing in Chrome & IE11 to get this value. YMMV.
    var maxYear = 275760;

    var isValidYear = !isNaN(yyyy) && yyyy <= maxYear;

    var isDivisbleBy4 = (yyyy % 4 === 0);
    var isDivisbleBy100 = (yyyy % 100 === 0);
    var isDivisbleBy400 = (yyyy % 400 === 0);
    var isLeapYear = (isDivisbleBy4 && !isDivisbleBy100) || isDivisbleBy400;

    var isValidMonth = !isNaN(mm) && (mm >= 1 && mm <= 12);
    if (!isValidMonth) {
        return false;
    }

    var maxDaysInMonth = 28;

    if (d31.indexOf(mm) > -1) {
        maxDaysInMonth = 31;
    } else if (d30.indexOf(mm) > -1) {
        maxDaysInMonth = 30;
    } else if (isLeapYear) {
        maxDaysInMonth = 29;
    }

    var isValidDay = !isNaN(dd) && (dd > 0 && dd <= maxDaysInMonth);
    if (!isValidDay) {
        return false;
    }

    return isValidMonth && isValidDay && isValidYear;
}

var testsThatShouldFail = [
    '13/77/7777', // lousy Smarch weather!
    '2/29/2018',
    '9/12/275761',
    '4/31/2016',
    '6/35/2019',
];

var testsThatShouldPass = [
    '1/1/1900',
    '2/29/2000',
    '2/29/2016',
    '9/12/275760',
    '8/16/2018',
];

console.log('should fail', testsThatShouldFail.map(isValidDateString));
console.log('should pass', testsThatShouldPass.map(isValidDateString));