如何在 JavaScript 中使用格式“ mm/dd/yyyy”验证日期?

我想使用格式 mm/dd/yyyy在输入上验证 日期格式

我在一个网站上找到了下面的代码,然后使用了它,但是没有用:

function isDate(ExpiryDate) {
var objDate,  // date object initialized from the ExpiryDate string
mSeconds, // ExpiryDate in milliseconds
day,      // day
month,    // month
year;     // year
// date length should be 10 characters (no more no less)
if (ExpiryDate.length !== 10) {
return false;
}
// third and sixth character should be '/'
if (ExpiryDate.substring(2, 3) !== '/' || ExpiryDate.substring(5, 6) !== '/') {
return false;
}
// extract month, day and year from the ExpiryDate (expected format is mm/dd/yyyy)
// subtraction will cast variables to integer implicitly (needed
// for !== comparing)
month = ExpiryDate.substring(0, 2) - 1; // because months in JS start from 0
day = ExpiryDate.substring(3, 5) - 0;
year = ExpiryDate.substring(6, 10) - 0;
// test year range
if (year < 1000 || year > 3000) {
return false;
}
// convert ExpiryDate to milliseconds
mSeconds = (new Date(year, month, day)).getTime();
// initialize Date() object from calculated milliseconds
objDate = new Date();
objDate.setTime(mSeconds);
// compare input date and parts from Date() object
// if difference exists then date isn't valid
if (objDate.getFullYear() !== year ||
objDate.getMonth() !== month ||
objDate.getDate() !== day) {
return false;
}
// otherwise return true
return true;
}


function checkDate(){
// define date string to test
var ExpiryDate = document.getElementById(' ExpiryDate').value;
// check date and print message
if (isDate(ExpiryDate)) {
alert('OK');
}
else {
alert('Invalid date format!');
}
}

有什么建议吗?

541502 次浏览

对于 mm/dd/yyyy 格式的日期,它似乎工作得很好,例如:

Http://jsfiddle.net/niklasvh/xfrlm/

我对你的代码唯一的问题是:

var ExpiryDate = document.getElementById(' ExpiryDate').value;

在元素 ID 之前的括号内有一个空格。将其更改为:

var ExpiryDate = document.getElementById('ExpiryDate').value;

没有任何关于不工作的数据类型的进一步详细信息,就没有太多其他可供输入的内容。

我觉得尼克拉斯能解决你的问题。除此之外,我认为下面的日期验证函数更容易阅读:

// Validates that the input string is a valid date formatted as "mm/dd/yyyy"
function isValidDate(dateString)
{
// First check for the pattern
if(!/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(dateString))
return false;


// Parse the date parts to integers
var parts = dateString.split("/");
var day = parseInt(parts[1], 10);
var month = parseInt(parts[0], 10);
var year = parseInt(parts[2], 10);


// Check the ranges of month and year
if(year < 1000 || year > 3000 || month == 0 || month > 12)
return false;


var monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];


// Adjust for leap years
if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
monthLength[1] = 29;


// Check the range of the day
return day > 0 && day <= monthLength[month - 1];
};

使用以下正则表达式进行验证:

var date_regex = /^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/;
if (!(date_regex.test(testDate))) {
return false;
}

对于 MM/dd/yyyy 来说,这是有效的。

所有的荣誉都属于 Elian-Ebbing

对于这里的懒人,我还提供了格式为 呀呀呀的自定义版本的函数。

function isValidDate(dateString)
{
// First check for the pattern
var regex_date = /^\d{4}\-\d{1,2}\-\d{1,2}$/;


if(!regex_date.test(dateString))
{
return false;
}


// Parse the date parts to integers
var parts   = dateString.split("-");
var day     = parseInt(parts[2], 10);
var month   = parseInt(parts[1], 10);
var year    = parseInt(parts[0], 10);


// Check the ranges of month and year
if(year < 1000 || year > 3000 || month == 0 || month > 12)
{
return false;
}


var monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];


// Adjust for leap years
if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
{
monthLength[1] = 29;
}


// Check the range of the day
return day > 0 && day <= monthLength[month - 1];
}

在下面的代码中找到,该代码允许对所提供的任何格式执行日期验证,以验证 start/from 和 end/to date。可能有一些更好的方法,但已经提出了这一点。注意提供的日期格式和日期字符串齐头并进。

<script type="text/javascript">
function validate() {


var format = 'yyyy-MM-dd';


if(isAfterCurrentDate(document.getElementById('start').value, format)) {
alert('Date is after the current date.');
} else {
alert('Date is not after the current date.');
}
if(isBeforeCurrentDate(document.getElementById('start').value, format)) {
alert('Date is before current date.');
} else {
alert('Date is not before current date.');
}
if(isCurrentDate(document.getElementById('start').value, format)) {
alert('Date is current date.');
} else {
alert('Date is not a current date.');
}
if (isBefore(document.getElementById('start').value, document.getElementById('end').value, format)) {
alert('Start/Effective Date cannot be greater than End/Expiration Date');
} else {
alert('Valid dates...');
}
if (isAfter(document.getElementById('start').value, document.getElementById('end').value, format)) {
alert('End/Expiration Date cannot be less than Start/Effective Date');
} else {
alert('Valid dates...');
}
if (isEquals(document.getElementById('start').value, document.getElementById('end').value, format)) {
alert('Dates are equals...');
} else {
alert('Dates are not equals...');
}
if (isDate(document.getElementById('start').value, format)) {
alert('Is valid date...');
} else {
alert('Is invalid date...');
}
}


/**
* This method gets the year index from the supplied format
*/
function getYearIndex(format) {


var tokens = splitDateFormat(format);


if (tokens[0] === 'YYYY'
|| tokens[0] === 'yyyy') {
return 0;
} else if (tokens[1]=== 'YYYY'
|| tokens[1] === 'yyyy') {
return 1;
} else if (tokens[2] === 'YYYY'
|| tokens[2] === 'yyyy') {
return 2;
}
// Returning the default value as -1
return -1;
}


/**
* This method returns the year string located at the supplied index
*/
function getYear(date, index) {


var tokens = splitDateFormat(date);
return tokens[index];
}


/**
* This method gets the month index from the supplied format
*/
function getMonthIndex(format) {


var tokens = splitDateFormat(format);


if (tokens[0] === 'MM'
|| tokens[0] === 'mm') {
return 0;
} else if (tokens[1] === 'MM'
|| tokens[1] === 'mm') {
return 1;
} else if (tokens[2] === 'MM'
|| tokens[2] === 'mm') {
return 2;
}
// Returning the default value as -1
return -1;
}


/**
* This method returns the month string located at the supplied index
*/
function getMonth(date, index) {


var tokens = splitDateFormat(date);
return tokens[index];
}


/**
* This method gets the date index from the supplied format
*/
function getDateIndex(format) {


var tokens = splitDateFormat(format);


if (tokens[0] === 'DD'
|| tokens[0] === 'dd') {
return 0;
} else if (tokens[1] === 'DD'
|| tokens[1] === 'dd') {
return 1;
} else if (tokens[2] === 'DD'
|| tokens[2] === 'dd') {
return 2;
}
// Returning the default value as -1
return -1;
}


/**
* This method returns the date string located at the supplied index
*/
function getDate(date, index) {


var tokens = splitDateFormat(date);
return tokens[index];
}


/**
* This method returns true if date1 is before date2 else return false
*/
function isBefore(date1, date2, format) {
// Validating if date1 date is greater than the date2 date
if (new Date(getYear(date1, getYearIndex(format)),
getMonth(date1, getMonthIndex(format)) - 1,
getDate(date1, getDateIndex(format))).getTime()
> new Date(getYear(date2, getYearIndex(format)),
getMonth(date2, getMonthIndex(format)) - 1,
getDate(date2, getDateIndex(format))).getTime()) {
return true;
}
return false;
}


/**
* This method returns true if date1 is after date2 else return false
*/
function isAfter(date1, date2, format) {
// Validating if date2 date is less than the date1 date
if (new Date(getYear(date2, getYearIndex(format)),
getMonth(date2, getMonthIndex(format)) - 1,
getDate(date2, getDateIndex(format))).getTime()
< new Date(getYear(date1, getYearIndex(format)),
getMonth(date1, getMonthIndex(format)) - 1,
getDate(date1, getDateIndex(format))).getTime()
) {
return true;
}
return false;
}


/**
* This method returns true if date1 is equals to date2 else return false
*/
function isEquals(date1, date2, format) {
// Validating if date1 date is equals to the date2 date
if (new Date(getYear(date1, getYearIndex(format)),
getMonth(date1, getMonthIndex(format)) - 1,
getDate(date1, getDateIndex(format))).getTime()
=== new Date(getYear(date2, getYearIndex(format)),
getMonth(date2, getMonthIndex(format)) - 1,
getDate(date2, getDateIndex(format))).getTime()) {
return true;
}
return false;
}


/**
* This method validates and returns true if the supplied date is
* equals to the current date.
*/
function isCurrentDate(date, format) {
// Validating if the supplied date is the current date
if (new Date(getYear(date, getYearIndex(format)),
getMonth(date, getMonthIndex(format)) - 1,
getDate(date, getDateIndex(format))).getTime()
=== new Date(new Date().getFullYear(),
new Date().getMonth(),
new Date().getDate()).getTime()) {
return true;
}
return false;
}


/**
* This method validates and returns true if the supplied date value
* is before the current date.
*/
function isBeforeCurrentDate(date, format) {
// Validating if the supplied date is before the current date
if (new Date(getYear(date, getYearIndex(format)),
getMonth(date, getMonthIndex(format)) - 1,
getDate(date, getDateIndex(format))).getTime()
< new Date(new Date().getFullYear(),
new Date().getMonth(),
new Date().getDate()).getTime()) {
return true;
}
return false;
}


/**
* This method validates and returns true if the supplied date value
* is after the current date.
*/
function isAfterCurrentDate(date, format) {
// Validating if the supplied date is before the current date
if (new Date(getYear(date, getYearIndex(format)),
getMonth(date, getMonthIndex(format)) - 1,
getDate(date, getDateIndex(format))).getTime()
> new Date(new Date().getFullYear(),
new Date().getMonth(),
new Date().getDate()).getTime()) {
return true;
}
return false;
}


/**
* This method splits the supplied date OR format based
* on non alpha numeric characters in the supplied string.
*/
function splitDateFormat(dateFormat) {
// Spliting the supplied string based on non characters
return dateFormat.split(/\W/);
}


/*
* This method validates if the supplied value is a valid date.
*/
function isDate(date, format) {
// Validating if the supplied date string is valid and not a NaN (Not a Number)
if (!isNaN(new Date(getYear(date, getYearIndex(format)),
getMonth(date, getMonthIndex(format)) - 1,
getDate(date, getDateIndex(format))))) {
return true;
}
return false;
}
</script>

下面是 HTML 代码片段

<input type="text" name="start" id="start" size="10" value="" />
<br/>
<input type="text" name="end" id="end" size="10" value="" />
<br/>
<input type="button" value="Submit" onclick="javascript:validate();" />

我从另一篇发现 给你的文章中提取了大部分代码。我已经为了我的目的修改了它。这对我的需求很有帮助。也许对你的情况有帮助。

$(window).load(function() {
function checkDate() {
var dateFormat = /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/;
var valDate = $(this).val();
if ( valDate.match( dateFormat )) {
$(this).css("border","1px solid #cccccc","color", "#555555", "font-weight", "normal");
var seperator1 = valDate.split('/');
var seperator2 = valDate.split('-');


if ( seperator1.length > 1 ) {
var splitdate = valDate.split('/');
} else if ( seperator2.length > 1 ) {
var splitdate = valDate.split('-');
}


var dd = parseInt(splitdate[0]);
var mm = parseInt(splitdate[1]);
var yy = parseInt(splitdate[2]);
var ListofDays = [31,28,31,30,31,30,31,31,30,31,30,31];


if ( mm == 1 || mm > 2 ) {
if ( dd > ListofDays[mm - 1] ) {
$(this).val("");
$(this).css("border","solid red 1px","color", "red", "font-weight", "bold");
alert('Invalid Date! You used a date which does not exist in the known calender.');
return false;
}
}


if ( mm == 2 ) {
var lyear = false;
if ( (!(yy % 4) && yy % 100) || !(yy % 400) ){
lyear = true;
}


if ( (lyear==false) && (dd>=29) ) {
$(this).val("");
$(this).css("border","solid red 1px","color", "red", "font-weight", "bold");
alert('Invalid Date! You used Feb 29th for an invalid leap year');
return false;
}


if ( (lyear==true) && (dd>29) ) {
$(this).val("");
$(this).css("border","solid red 1px","color", "red", "font-weight", "bold");
alert('Invalid Date! You used a date greater than Feb 29th in a valid leap year');
return false;
}
}
} else {
$(this).val("");
$(this).css("border","solid red 1px","color", "red", "font-weight", "bold");
alert('Date format was invalid! Please use format mm/dd/yyyy');
return false;
}
};


$('#from_date').change( checkDate );
$('#to_date').change( checkDate );
});
var date = new Date(date_string)

返回任何无效 date _ string 的文本 'Invalid Date'

注意: 请看下面的评论。

如果给定的字符串格式正确(‘ MM/DD/YYYY’) ,函数将返回 true,否则将返回 false。(我在网上找到了这个代码,稍微修改了一下)

function isValidDate(date) {
var temp = date.split('/');
var d = new Date(temp[2] + '/' + temp[0] + '/' + temp[1]);
return (d && (d.getMonth() + 1) == temp[0] && d.getDate() == Number(temp[1]) && d.getFullYear() == Number(temp[2]));
}


console.log(isValidDate('02/28/2015'));

我将使用 等一下进行日期验证。

alert(moment("05/22/2012", 'MM/DD/YYYY',true).isValid()); //true

http://jsfiddle.net/q8y9nbu5/

true的价值是 严格的分析的信用@Andrey Prokhorov,这意味着

您可以为最后一个参数指定一个布尔值,以便 Moment 使用 严格解析。严格解析要求格式和输入 完全匹配,包括分界线。

类似于 Elian Ebbing 的回答,但是支持“”,“/”,“ .”,“-”,“”分隔符

function js_validate_date_dmyyyy(js_datestr)
{
var js_days_in_year = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
var js_datepattern = /^(\d{1,2})([\.\-\/\\ ])(\d{1,2})([\.\-\/\\ ])(\d{4})$/;


if (! js_datepattern.test(js_datestr)) { return false; }


var js_match = js_datestr.match(js_datepattern);
var js_day = parseInt(js_match[1]);
var js_delimiter1 = js_match[2];
var js_month = parseInt(js_match[3]);
var js_delimiter2 = js_match[4];
var js_year = parseInt(js_match[5]);


if (js_is_leap_year(js_year)) { js_days_in_year[2] = 29; }


if (js_delimiter1 !== js_delimiter2) { return false; }
if (js_month === 0  ||  js_month > 12)  { return false; }
if (js_day === 0  ||  js_day > js_days_in_year[js_month])   { return false; }


return true;
}


function js_is_leap_year(js_year)
{
if(js_year % 4 === 0)
{
if(js_year % 100 === 0)
{
if(js_year % 400 === 0)
{
return true;
}
else return false;
}
else return true;
}
return false;
}
function fdate_validate(vi)
{
var parts =vi.split('/');
var result;
var mydate = new Date(parts[2],parts[1]-1,parts[0]);
if (parts[2] == mydate.getYear() && parts[1]-1 == mydate.getMonth() && parts[0] == mydate.getDate() )
{result=0;}
else
{result=1;}
return(result);
}

下面是检查有效日期的一个片段:

function validateDate(dateStr) {
const regExp = /^(\d\d?)\/(\d\d?)\/(\d{4})$/;
let matches = dateStr.match(regExp);
let isValid = matches;
let maxDate = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
   

if (matches) {
const month = parseInt(matches[1]);
const date = parseInt(matches[2]);
const year = parseInt(matches[3]);
     

isValid = month <= 12 && month > 0;
isValid &= date <= maxDate[month] && date > 0;
     

const leapYear = (year % 400 == 0)
|| (year % 4 == 0 && year % 100 != 0);
isValid &= month != 2 || leapYear || date <= 28;
}
   

return isValid
}


console.log(['1/1/2017', '01/1/2017', '1/01/2017', '01/01/2017', '13/12/2017', '13/13/2017', '12/35/2017'].map(validateDate));

你可以用 Date.parse()

你可以读 MDN 文档

Parse ()方法解析日期的字符串表示形式,并且 返回自1970年1月1日以来的毫秒数 如果字符串无法识别,或者在某些情况下包含 非法的日期值(例如2015-02-31)。

检查 Date.parse的结果是否为 NaN

let isValidDate = Date.parse('01/29/1980');


if (isNaN(isValidDate)) {
// when is not valid date logic


return false;
}


// when is valid date logic

请看一下什么时候推荐在 MDN 中使用 Date.parse

如果您想要验证 dd/MM/yyyy,那么可以使用它

function isValidDate(date) {
var temp = date.split('/');
var d = new Date(temp[1] + '/' + temp[0] + '/' + temp[2]);
return (d && (d.getMonth() + 1) == temp[1] && d.getDate() == Number(temp[0]) && d.getFullYear() == Number(temp[2]));
}


alert(isValidDate('29/02/2015')); // it not exist ---> false

现在是解决问题的好时机。我认为没有理由仅仅为了检查日期而增加复杂性... 看看时刻: http://momentjs.com/

HTML:

<input class="form-control" id="date" name="date" onchange="isValidDate(this);" placeholder="DD/MM/YYYY" type="text" value="">

剧本:

 function isValidDate(dateString)  {
var dateToValidate = dateString.value
var isValid = moment(dateToValidate, 'MM/DD/YYYY',true).isValid()
if (isValid) {
dateString.style.backgroundColor = '#FFFFFF';
} else {
dateString.style.backgroundColor = '#fba';
}
};

首先将字符串日期转换为 js 日期格式,再转换为字符串格式,然后与原始字符串进行比较。

function dateValidation(){
var dateString = "34/05/2019"
var dateParts = dateString.split("/");
var date= new Date(+dateParts[2], dateParts[1] - 1, +dateParts[0]);


var isValid = isValidDate( dateString, date );
console.log("Is valid date: " + isValid);
}


function isValidDate(dateString, date) {
var newDateString = ( date.getDate()<10 ? ('0'+date.getDate()) : date.getDate() )+ '/'+ ((date.getMonth() + 1)<10? ('0'+(date.getMonth() + 1)) : (date.getMonth() + 1) )  + '/' +  date.getFullYear();
return ( dateString == newDateString);
}
  1. Javascript

    function validateDate(date) {
    try {
    new Date(date).toISOString();
    return true;
    } catch (e) {
    return false;
    }
    }
    
  2. JQuery

    $.fn.validateDate = function() {
    try {
    new Date($(this[0]).val()).toISOString();
    return true;
    } catch (e) {
    return false;
    }
    }
    

returns true for a valid date string.

我们可以使用定制的功能或日期模式。下面的代码是定制的功能,根据您的要求,请更改它。

 function isValidDate(str, separator = '-') {
var getvalue = str.split(separator);
var day = parseInt(getvalue[2]);
var month = parseInt(getvalue[1]);
var year = parseInt(getvalue[0]);
if(year < 1901 || year > 2100){
return false;
}
if (month < 1 || month > 12) {
return false;
}
if (day < 1 || day > 31) {
return false;
}
if ((month==4 && month==6 && month==9 && month==11) && day==31) {
return false;
}
if (month == 2) { // check for february 29th
var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
if (day>29 || (day==29 && !isleap)) {
return false;
}
}
else{
return true;
}
return true;
}

很少见到一篇关于这样一个基本话题的帖子这么老,有这么多的答案,没有一个是正确的。(我不是说它们都不管用。)

  • 这不需要一个闰年决定程序,语言可以为我们做这些工作。
  • 这不需要时间。
  • Date.parse()不应该用于本地日期字符串。MDN说: “不建议使用 Date.parse,因为直到 ES5,字符串的解析完全依赖于实现。”该标准需要一个(可能被简化的) ISO8601字符串; 对任何其他格式的支持都是依赖于实现的。
  • 也不应该使用 new Date(string),因为它使用 Date.parse ()。
  • 我认为闰日应该是有效的。
  • 验证函数必须考虑到输入字符串与预期格式不匹配的可能性。例如,“1a/2a/3aaa”、“1234567890”或“ ab/cd/efgh”。

这是一个没有隐式转换的高效、简洁的解决方案。它利用了 Date 构造函数将2018-14-29解释为2019-03-01的意愿。它确实使用了一些现代语言特性,但是如果需要的话,这些特性很容易被删除。我还包括了一些测试。

function isValidDate(s) {
// Assumes s is "mm/dd/yyyy"
if ( ! /^\d\d\/\d\d\/\d\d\d\d$/.test(s) ) {
return false;
}
const parts = s.split('/').map((p) => parseInt(p, 10));
parts[0] -= 1;
const d = new Date(parts[2], parts[0], parts[1]);
return d.getMonth() === parts[0] && d.getDate() === parts[1] && d.getFullYear() === parts[2];
}


function testValidDate(s) {
console.log(s, isValidDate(s));
}
testValidDate('01/01/2020'); // true
testValidDate('02/29/2020'); // true
testValidDate('02/29/2000'); // true
testValidDate('02/29/1900'); // false
testValidDate('02/29/2019'); // false
testValidDate('01/32/1970'); // false
testValidDate('13/01/1970'); // false
testValidDate('14/29/2018'); // false
testValidDate('1a/2b/3ccc'); // false
testValidDate('1234567890'); // false
testValidDate('aa/bb/cccc'); // false
testValidDate(null);         // false
testValidDate('');           // false

在@Jay Dunnings 的回答中扩展(或者更好地收缩) ,下面的 双线使用了 Intl API 和 ES6解构。它通过了 Jay Dunning 的所有测试。

/**
* @param {string} date
* @returns {boolean} true if date is of the form mm/dd/yyyy
*/
function is_en_US_date(date) {
const [match, mm, dd, yyyy] = /^(\d\d)[/](\d\d)[/](\d{4})$/.exec(date) || [];
return match !== undefined && new Intl.DateTimeFormat('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' }).format(new Date(yyyy, mm-1, dd)) === date
}

日期很复杂。 验证它的最佳方法是使用像 Luxon约会DayJS这样的软件包。

使用日期 -fns:

import {isMatch} from 'date-fns'


const match = isMatch('12/25/2010', 'MM/dd/yyyy') // true

function validatedate(inputText, dateFormat) {
var minYear = 1950;
var maxYear = 2050;
inputText = inputText.replace("A", "a");
inputText = inputText.replace("B", "b");
inputText = inputText.replace("C", "c");
inputText = inputText.replace("D", "d");
inputText = inputText.replace("E", "e");
inputText = inputText.replace("F", "f");
inputText = inputText.replace("G", "g");
inputText = inputText.replace("H", "h");
inputText = inputText.replace("I", "i");
inputText = inputText.replace("J", "j");
inputText = inputText.replace("K", "k");
inputText = inputText.replace("L", "l");
inputText = inputText.replace("M", "m");
inputText = inputText.replace("O", "o");
inputText = inputText.replace("P", "p");
inputText = inputText.replace("Q", "q");
inputText = inputText.replace("R", "r");
inputText = inputText.replace("S", "s");
inputText = inputText.replace("T", "t");
inputText = inputText.replace("U", "u");
inputText = inputText.replace("V", "v");
inputText = inputText.replace("W", "w");
inputText = inputText.replace("X", "x");
inputText = inputText.replace("Y", "y");
inputText = inputText.replace("Z", "z");
if (dateFormat == "dd/mmm/yyyy" || dateFormat == "dd-mmm-yyyy" || dateFormat == "dd.mmm.yyyy" || dateFormat == "dd/yyyy/mmm" || dateFormat == "dd-yyyy-mmm" || dateFormat == "dd.yyyy.mmm" || dateFormat == "mmm/dd/yyyy" || dateFormat == "mmm-dd-yyyy" || dateFormat == "mmm.dd.yyyy" || dateFormat == "mmm/yyyy/dd" || dateFormat == "mmm-yyyy-dd" || dateFormat == "mmm.yyyy.dd" || dateFormat == "yyyy/mmm/dd" || dateFormat == "yyyy-mmm-dd" || dateFormat == "yyyy.mmm.dd" || dateFormat == "yyyy/dd/mmm" || dateFormat == "yyyy-dd-mmm" || dateFormat == "yyyy.dd.mmm") {
dateFormat = dateFormat.replace("mmm", "mm");
inputText = inputText.replace("jan", "01");
inputText = inputText.replace("feb", "02");
inputText = inputText.replace("mar", "03");
inputText = inputText.replace("apr", "04");
inputText = inputText.replace("may", "05");
inputText = inputText.replace("jun", "06");
inputText = inputText.replace("jul", "07");
inputText = inputText.replace("aug", "08");
inputText = inputText.replace("sep", "09");
inputText = inputText.replace("oct", "10");
inputText = inputText.replace("nov", "11");
inputText = inputText.replace("dec", "12");
}




var w;
var q;
var delm;
delm1 = "/";


for (w = 0; w < inputText.length; w++) {
q = inputText.charAt(w);
if (q == '0' || q == '1' || q == '2' || q == '3' || q == '4' || q == '5' || q == '6' || q == '7' || q == '8' || q == '9' || q == '/') {} else {
delm1 = "";
}
}
delm2 = "-";


for (w = 0; w < inputText.length; w++) {
q = inputText.charAt(w);
if (q == '0' || q == '1' || q == '2' || q == '3' || q == '4' || q == '5' || q == '6' || q == '7' || q == '8' || q == '9' || q == '-') {} else {
delm2 = "";
}
}


delm3 = ".";


for (w = 0; w < inputText.length; w++) {
q = inputText.charAt(w);
if (q == '0' || q == '1' || q == '2' || q == '3' || q == '4' || q == '5' || q == '6' || q == '7' || q == '8' || q == '9' || q == '.') {} else {
delm3 = "";
}
}


var delm;
if (delm1 == "/" && (dateFormat == "dd/mm/yyyy" || dateFormat == "mm/dd/yyyy" || dateFormat == "dd/yyyy/mm" || dateFormat == "mm/yyyy/dd" || dateFormat == "yyyy/mm/dd" || dateFormat == "yyyy/dd/mm")) {
delm = "/";
}


if (delm2 == "-" && (dateFormat == "dd-mm-yyyy" || dateFormat == "mm-dd-yyyy" || dateFormat == "dd-yyyy-mm" || dateFormat == "mm-yyyy-dd" || dateFormat == "yyyy-mm-dd" || dateFormat == "yyyy-dd-mm")) {
delm = "-";
}
if (delm3 == "." && (dateFormat == "dd.mm.yyyy" || dateFormat == "mm.dd.yyyy" || dateFormat == "dd.yyyy.mm" || dateFormat == "mm.yyyy.dd" || dateFormat == "yyyy.mm.dd" || dateFormat == "yyyy.dd.mm")) {
delm = ".";
}


var invalid;
var f = "31/12/2000";
f = inputText;
var ln = f.length;
var dt;
var mn;
var yr;
var t = f.split(delm);
var j = t.length;
if (j == 3) {
dt = t[0];
mn = t[1];
yr = t[2];


if (dateFormat == "mm.dd.yyyy" || dateFormat == "mm/dd/yyyy" || dateFormat == "mm-dd-yyyy") {
var tmp = mn;
mn = dt;
dt = tmp;
}


if (dateFormat == "dd.yyyy.mm" || dateFormat == "dd/yyyy/mm" || dateFormat == "dd-yyyy-mm") {
var tmp = mn;
mn = yr;
yr = tmp;
}
if (dateFormat == "mm.yyyy.dd" || dateFormat == "mm/yyyy/dd" || dateFormat == "mm-yyyy-dd") {
var m1 = mn;
var d1 = dt;
var y1 = yr;
mn = d1;
yr = m1;
dt = y1;
}


if (dateFormat == "yyyy.mm.dd" || dateFormat == "yyyy/mm/dd" || dateFormat == "yyyy-mm-dd") {
var m1 = mn;
var d1 = dt;
var y1 = yr;
mn = m1;
yr = d1;
dt = y1;
}


if (dateFormat == "yyyy.dd.mm" || dateFormat == "yyyy/dd/mm" || dateFormat == "yyyy-dd-mm") {
var m1 = mn;
var d1 = dt;
var y1 = yr;
mn = y1;
yr = d1;
dt = m1;
}


if (parseInt(yr) >= parseInt(minYear) && parseInt(yr) <= parseInt(maxYear)) {
// do nothing
} else {
invalid = "true";
}
if (mn.length > 2) {
invalid = "true";
}
if (dt.length > 2) {
invalid = "true";
}


if (t[0] == "") {
invalid = "true";
}
if (t[1] == "") {
invalid = "true";
}
if (t[2] == "") {
invalid = "true";
}


if (j != 3) {
invalid = "true";
}
var dc;
var daysArray = "0-31-28-31-30-31-30-31-31-30-31-30-31";


if ((yr % 4) == 0) {
daysArray = "0-31-29-31-30-31-30-31-31-30-31-30-31";
}
var days = daysArray.split("-");
if (parseInt(dt) >= 1 && parseInt(dt) <= days[parseInt(mn)]) {} else {
invalid = "true";
}


if (yr.length != 4) {
invalid = "true";
}


var i;
var m;


for (i = 0; i < ln; i++) {
m = f.charAt(i);
if (m == '0' || m == '1' || m == '2' || m == '3' || m == '4' || m == '5' || m == '6' || m == '7' || m == '8' || m == '9' || m == delm) {} else {
invalid = "true";
}
}
} else {
invalid = "true";
}


if (invalid == "true") {
alert("Invalid Date");
} else {
alert("valid Date");
}


}

function validatedate(inputText, DateFormat) {
// format dd/mm/yyyy or in any order of (dd or mm or yyyy) you can write dd or mm or yyyy in first or second or third position ... or can be slash"/" or dot"." or dash"-" in the dates formats
var invalid = "";
var dt = "";
var mn = "";
var yr = "";
var k;
var delm = DateFormat.includes("/") ? "/" : ( DateFormat.includes("-") ? "-" : ( DateFormat.includes(".") ? "." : "" ) ) ;
var f1 = inputText.split(delm);
var f2 = DateFormat.split(delm);
for(k=0;k<=2;k++) {
dt = dt + (f2[parseInt(k)]=="dd" ? f1[parseInt(k)] : "");
mn = mn + (f2[parseInt(k)]=="mm" ? f1[parseInt(k)] : "");
yr = yr + (f2[parseInt(k)]=="yyyy" ? f1[parseInt(k)] : "");
}
var mn_days = "0-31-" + (yr % 4 == 0 ? 29 : 28) + "-31-30-31-30-31-31-30-31-30-31";
var days = mn_days.split("-");
if (f1.length!=3 ||
mn.length>2 ||
dt.length>2 ||
yr.length!=4 ||
!(parseInt(mn)>=1 && parseInt(mn)<=12) ||
!(parseInt(yr)>=parseInt(1900) && parseInt(yr)<=parseInt(2100)) ||
!(parseInt(dt)>=1 && parseInt(dt)<=parseInt(days[parseInt(mn)]))) {
invalid = "true";
}
alert( ( invalid=="true" ? "Invalid Date" : "Valid Date")  );
}

另一种选择

我知道,这个问题已经得到了令人作呕的回答,但我还是想提出一个替代解决方案,让自己陷入这样的困境。

AFAICT,这个方法在其他任何答案中都没有出现。也许还有一些我没考虑到的边缘情况... ... 我相信如果是这样的话,你们一定会适时地嘲笑我的。

有人曾经说过——耶稣或者孔子,也许——

当您决定用正则表达式解决问题时, 现在你有两个问题

也就是说,我喜欢正则表达式,并且经常在其他事情上使用它; 然而,最近,我遇到了一个问题,其中一个顶级答案出现在这里,它抛出了一个无效日期的假阳性。它使用了过于严格的正则表达式。我用以下代码替换了对日期字符串(dd/dd/dddd)的上述检查:

const isInvalidDate = (dateString) => new Date(dateString).toString() === 'Invalid Date'


console.log(isInvalidDate('asdf')) //> true
console.log(isInvalidDate('09/29/1985')) //> false

编辑2022

我的另一个解决方案自从我发布以来一直保持不变,但也许可以更好地用非负面的形式来写,以最大限度地减少认知压力。所以,如果你要复制粘贴它,那就复制粘贴这个:

const isValidDate = (dateString) => new Date(dateString).toString() !== 'Invalid Date'


console.log(isValidDate('asdf')) //> false
console.log(isValidDate('09/29/1985')) //> true

为什么我还在说话?

正如@jay-dunning 上面指出的,这个解决方案对于某些应用程序可能并不理想(大概是在 < ES5中实现的那些应用程序?咳嗽).我完全没有被迫停止使用我的解决方案,但是要注意:

  • Parse ()不应该用于本地日期字符串。MDN 说: “在 ES5解析字符串之前,不建议使用 Date.parse 完全依赖于实现。”
    (可能被简化) ISO8601字符串; 支持任何其他
    格式依赖于实现。
  • 也不应该使用新的 Date (字符串) ,因为它使用 Date.parse ()。

function validateDate(dateStr) {
const regExp = /^(\d\d?)\/(\d\d?)\/(\d{4})$/;
let matches = dateStr.match(regExp);
let isValid = matches;
let maxDate = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
   

if (matches) {
const month = parseInt(matches[1]);
const date = parseInt(matches[2]);
const year = parseInt(matches[3]);
     

isValid = month <= 12 && month > 0;
isValid &= date <= maxDate[month] && date > 0;
     

const leapYear = (year % 400 == 0)
|| (year % 4 == 0 && year % 100 != 0);
isValid &= month != 2 || leapYear || date <= 28;
}
   

return isValid
}


console.log(['1/1/2017', '01/1/2017', '1/01/2017', '01/01/2017', '13/12/2017', '13/13/2017', '12/35/2017'].map(validateDate));