2

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

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

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

3 回答 3

12

您必须决定要接受哪种形式的约会。

然后,一旦你知道你想接受什么形式,你就可以检查MDNnew Date(str)date.parse() MDN 上的规范,看看它是否完全支持你想要的,以及它是否在错误条件下做正确的事情(它可能不会)。如果没有,那么您将不得不进行一些手动解析。

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

还有一些浏览器差异,因为 javascript 已经开始支持其他日期格式,并且早期的浏览器之间存在一些不一致,这意味着您需要自己构建一个简单的测试脚本,其中包含一堆合法和非法的日期格式字符串,看看是否您的有效性检测可以在多个浏览器中执行您想要的操作。这不是火箭科学,但它也不是微不足道的,需要一些工作,除非您只想接受原始日期对象支持的内容(这不太可能)。

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

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

这是一个接受这些美国格式的手动解析函数的示例:

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/

如果您想要欧元格式,将代码切换到该格式是一件小事。无论哪种情况,您都必须决定接受哪种格式,为其编码,然后与用户沟通需要哪种格式。如果您认为这很混乱,那么也许您会明白为什么这么多网站使用没有这种复杂性的日期日历选择器。

于 2012-04-21T21:43:51.013 回答
1

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

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

这就是为什么它过于简单化的原因。

首先,听起来您确实想检查Date 对象的字符串表示形式的有效性。这本身并不是特别有用,因为您将希望将日期用于脚本中的某些内容,将其发送到服务器等。

如果您想在脚本中使用日期,有一些警告

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;
}

这是强制性的现场演示

于 2012-04-22T21:09:10.527 回答
0

new Date()例如,如果 month>12 则不会引发异常,您可以使用Date.parse()并测试返回的值isNaN()

于 2012-04-21T21:28:06.527 回答