这是检查JavaScript中有效日期的好方法吗?

时间:2012-04-21 21:19:13

标签: javascript validation

请更正或解释我的过度简化是如何错误的,因为我不是JavaScript专家。

但我只需要知道一个对象是否是一个有效的日期。这只会来自用户输入(即文本框)。

var is_valid_date = function(date) {
    try {
        var d = new Date(date);
        return true;
    }
    catch(e) {
        return false;
    }
}

3 个答案:

答案 0 :(得分:11)

您必须决定要接受的日期形式。

然后,一旦您知道要接受哪些表单,就可以查看new Date(str)date.parse() on MDN的规范,看看它是否支持您想要的内容以及是否支持在错误条件下做正确的事情(可能不会)。如果没有,那么你将不得不做一些手动解析。

如果您需要我们的进一步帮助,您需要指定您希望接受的日期形式。

由于javascript已经移动以支持其他日期格式,而且之前的浏览器之间存在一些不一致,这也意味着您需要自己构建一个带有大量合法和非法日期格式字符串的简单测试脚本并查看您的有效性检测是否符合您在多个浏览器中的要求。要想做到这一点,这不是火箭科学,但它也不是微不足道的,需要一些工作,除非你只想接受原始日期对象所支持的东西(这是不太可能的)。

如果这是我的代码,我可能会认为手动解析您想要的输入格式的工作要少得多,您知道100%确定将在所有浏览器中工作,因为它是您自己的手动解析。我可能会使用正则表达式来解析日期,然后将每个组件转换为数字并检查每个组件的有效性。然后,您可以将这些数字组件提供给Date构造函数以创建Date对象。

如果你现在可以知道,内置日期类对用户输入的输入不是很有用。如果您愿意使用库,date.js library在这方面有很多有用的功能。

以下是接受这些美国格式的手动解析功能的示例:

mm-dd-yyyy
mm dd yyyy
mm/dd/yyyy

JS代码:

function checkDate(str) {
    var matches = str.match(/(\d{1,2})[- \/](\d{1,2})[- \/](\d{4})/);
    if (!matches) return;

    // parse each piece and see if it makes a valid date object
    var month = parseInt(matches[1], 10);
    var day = parseInt(matches[2], 10);
    var year = parseInt(matches[3], 10);
    var date = new Date(year, month - 1, day);
    if (!date || !date.getTime()) return;

    // make sure we have no funny rollovers that the date object sometimes accepts
    // month > 12, day > what's allowed for the month
    if (date.getMonth() + 1 != month ||
        date.getFullYear() != year ||
        date.getDate() != day) {
            return;
        }
    return(date);
}

包含一些测试用例的演示:http://jsfiddle.net/jfriend00/xZmBY/

如果你想要欧元格式,将代码切换到那个是一件小事。在任何一种情况下,您都必须决定接受哪种格式,为其编码,然后向用户传达所需的格式。如果您认为这很混乱,那么也许您会看到为什么这么多网站使用没有这种复杂性的日期日历选择器。

答案 1 :(得分:1)

  

请更正或解释我的过度简化是如何错误的,因为我不是JavaScript专家。

     

但我只需要知道一个对象是否是一个有效的日期。这只会来自用户输入(即文本框)。

这就是为什么它过于简单了。

首先,听起来你真的想要检查Date对象的字符串表示的有效性。这本身并不是特别有用,因为您将要在脚本中使用日期,将其发送到服务器等。

如果您想在脚本中使用日期,则有caveats

new Date('2020-10-10') // Fri Oct 09 2020 20:00:00 GMT-0400 (EDT)

如果您想将其传递给服务器,您需要做的不仅仅是检查有效性 - 您需要使用服务器端代码可以解释的格式。

如果是这种情况,您可以考虑将规范化字符串转换为您选择的格式。您希望能够在客户端和服务器端代码中从规范化字符串创建等效日期。为简单起见,格式可以是人类可读的(不是时间戳),您可以使用规范化字符串替换文本输入的值。

检查字符串的有效性只是标准化的一部分...如果输入错误,则返回函数返回false或空字符串,不要更改文本输入的值,而是显示一条消息,指示该值无效:

// assume `birthday` is a text input.

birthday.onblur = function() {

    var dateString = normalizeDate(birthday.value);

    if (dateString) {
        validator.style.display = 'none';
        birthday.value = dateString;
    } else {
        validator.style.display = 'block';
    }

}; 

以下是normalizeDate函数的外观示例。此示例使用格式'yyyy-mm-dd',您可以根据需要进行更改。

function normalizeDate(dateString) {

    // If it's not at least 6 characters long (8/8/88), give up.
    if (dateString.length && dateString.length < 6) {
        return '';
    }

    var date = new Date(dateString), 
        month, day;

    // If input format was in UTC time, adjust it to local.
    if (date.getHours() || date.getMinutes()) {
        date.setMinutes(date.getTimezoneOffset());
    }

    month = date.getMonth() + 1;
    day = date.getDate();

    // Return empty string for invalid dates
    if (!day) {
        return '';
    }

    // Return the normalized string.
    return date.getFullYear() + '-' +
        (month > 9 ? '' : '0') + month + '-' + 
        (day > 9 ? '' : '0') + day;
}

这是必须的live demo

答案 2 :(得分:0)

new Date()如果月份> 12,则不会抛出异常,例如,您可以使用Date.parse()并使用isNaN()

测试返回的值