这是在 JavaScript 中检查有效日期的好方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10263103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is this a good way to check for a valid date in JavaScript?
提问by cbmeeks
Please correct or explain how my over-simplification is incorrect as I am not a JavaScript expert.
请更正或解释我的过度简化是如何不正确的,因为我不是 JavaScript 专家。
But I just need to know if an object is a valid date. This will only come from user input (ie, text box).
但我只需要知道一个对象是否是有效日期。这只会来自用户输入(即文本框)。
var is_valid_date = function(date) {
try {
var d = new Date(date);
return true;
}
catch(e) {
return false;
}
}
回答by jfriend00
YOU have to decide what form of dates you want to accept.
您必须决定要接受的日期形式。
Then, once you know what forms you want to accept, you can then check the spec for new Date(str)
or date.parse()
on MDNand see if it supports exactly what you want and if it does the right things on error conditions (it probably will not). If not, then you will have to do some manual parsing.
然后,一旦你知道你想要接受什么形式,你就可以检查MDN 上的new Date(str)
或规范,看看它是否完全支持你想要的,以及它是否在错误条件下做正确的事情(可能不会)。如果没有,那么您将不得不进行一些手动解析。 date.parse()
If you want further help from us, you will need to specify what forms of date you want to accept.
如果您需要我们的进一步帮助,您需要指定您希望接受的日期形式。
There are also some browser differences as javascript has moved to support additional date formats and earlier browsers had some inconstencies between them which all means you'll want to build yourself a simple test script with a bunch of legal and illegal date format strings and see if your validity detection does what you want in several browsers. This isn't rocket science to get it right, but it's not trivial either and requires some work unless you only want to accept what the original date object supported (which is unlikely).
还有一些浏览器差异,因为 javascript 已经转向支持其他日期格式,并且早期的浏览器在它们之间存在一些不一致,这一切都意味着您需要使用一堆合法和非法的日期格式字符串构建自己的简单测试脚本,看看是否您的有效性检测在多个浏览器中执行您想要的操作。这不是正确的火箭科学,但它也不是微不足道的,并且需要一些工作,除非您只想接受原始日期对象支持的内容(这不太可能)。
If this were my code, I'd probably decide that it's far less work to do manual parsing of your desired input format that you know with 100% certainty will work in all browsers because it's your own manual parsing. I'd probably use a regex to parse the date and then convert each component to a number and check each component for validity. You can then feed those numeric components to the Date constructor to create the Date object.
如果这是我的代码,我可能会认为手动解析所需输入格式的工作要少得多,您知道 100% 肯定会在所有浏览器中工作,因为这是您自己的手动解析。我可能会使用正则表达式来解析日期,然后将每个组件转换为数字并检查每个组件的有效性。然后,您可以将这些数字组件提供给 Date 构造函数以创建 Date 对象。
If you can tell by now, the built-in date class isn't very useful for user entered input. If you're willing to use a library for this, the date.js libraryhas a ton of useful functionality in this regard.
如果您现在可以看出,内置日期类对于用户输入的输入并不是很有用。如果您愿意为此使用库,则date.js 库在这方面具有大量有用的功能。
Here's an example of a manual parsing function that accepts these US formats:
以下是接受这些美国格式的手动解析函数的示例:
mm-dd-yyyy
mm dd yyyy
mm/dd/yyyy
JS Code:
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);
}
And a demo with some test cases: http://jsfiddle.net/jfriend00/xZmBY/
和一些测试用例的演示:http: //jsfiddle.net/jfriend00/xZmBY/
If you want the Euro format, it's a trivial matter to switch the code to that. In either case, you have to decide which format you accept, code for it and then communicate to the user which format is required. If you think this is messy, then perhaps you will see why so many sites use a date calendar picker that doesn't have this complexity.
如果您想要欧元格式,将代码切换到该格式是一件小事。无论哪种情况,您都必须决定接受哪种格式,为其编码,然后与用户沟通所需的格式。如果您认为这很混乱,那么您也许会明白为什么这么多网站使用没有这种复杂性的日期日历选择器。
回答by Dagg Nabbit
Please correct or explain how my over-simplification is incorrect as I am not a JavaScript expert.
But I just need to know if an object is a valid date. This will only come from user input (ie, text box).
请更正或解释我的过度简化是如何不正确的,因为我不是 JavaScript 专家。
但我只需要知道一个对象是否是有效日期。这只会来自用户输入(即文本框)。
Here's why it's an oversimplification.
这就是为什么它过于简单化的原因。
First of all, it sounds like you really want to check the validity of a string representationof a Date object. This is not particularly useful by itself, because you are going to want to use the date for something in your script, send it to the server, etc.
首先,听起来您确实想检查Date 对象的字符串表示形式的有效性。这本身并不是特别有用,因为您将要在脚本中使用日期,将其发送到服务器等。
If you want to use the date in your script, there are caveats.
new Date('2020-10-10') // Fri Oct 09 2020 20:00:00 GMT-0400 (EDT)
If you want to pass it to the server, you'll need to do more than just check validity– you'll need to use a format that your server side code can interpret.
如果您想将它传递给服务器,您需要做的不仅仅是检查有效性——您需要使用服务器端代码可以解释的格式。
If that's the case, you could consider normalizingthe string into a format of your choice. You'd want to be able to create equivalent dates from the normalized strings in both your client and server side code. For simplicity, the format can be human-readable (not a timestamp), and you can replace the value of the text input with the normalized string.
如果是这种情况,您可以考虑将字符串规范化为您选择的格式。您希望能够从客户端和服务器端代码中的规范化字符串创建等效日期。为简单起见,格式可以是人类可读的(不是时间戳),并且您可以用规范化的字符串替换文本输入的值。
Checking the validity of the string can simply be a part of normalization... have the function return false
or an empty string if the input was bad, don't change the text input's value, and instead show a message indicating that the value is invalid:
检查字符串的有效性可以简单地作为规范化的一部分......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';
}
};
Here's an example of what the normalizeDate
function might look like. This example uses the format 'yyyy-mm-dd', you can change it to suit your needs.
下面是该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;
}
Here's the obligatory live demo.
这是强制性的现场演示。
回答by Soufiane Hassou
new Date()
doesn't throw an exception if month>12 for example, you can use Date.parse()
and test the returned value with isNaN()
new Date()
例如,如果月份> 12,则不会引发异常,您可以使用Date.parse()
并测试返回的值isNaN()