Javascript有效日期检查在IE8(和Firefox)中不起作用

我在JavaScript中检测了一个“无效日期”日期实例,用于检查有效日期,我尝试了两个流行的答案。 我在IE8中对它们进行了测试 – 不幸的是两者都令人失望。 在这里查看http://jsfiddle.net/Lijo/uzSU6/2/

有没有更好的JavaScript代码可以在IE8 + Chrome + Firefox中使用?

注意:令我惊讶的是,它在Firefox中也不能正常工作……

条件

日期格式应为带斜杠的美国日期格式(/)

在此处输入图像描述

isValidDateCheck2('12/33/2012') ; isValidDateCheck1('12/12/2012') ; function isValidDateCheck1(d) { alert(Object.prototype.toString.call(d)); if ( Object.prototype.toString.call(d) !== "[object Date]" ) { alert('Not Valid'); } if(!isNaN(d.getTime())) { alert(d.getTime()); } } function isValidDateCheck2(d) { var timestamp=Date.parse(d); alert(timestamp); if (isNaN(timestamp)==false) { var date=new Date(timestamp); alert(date); } } 

编辑

@mplungjan方法(首次提出)列于http://jsfiddle.net/Lijo/uzSU6/7/ 。 这在IE8中失败了一个场景 – http://jsfiddle.net/Lijo/uzSU6/12/ 。

你似乎在这里混淆了两件事。 有效日期对象和有效日期。 这些都不是同一个问题。

您链接的问题回答了如何测试日期对象的有效性(日期对象是否为“无效日期”实例)。 在构造它们时使用无效参数时会生成无效的日期对象: new Date('?')

您想要的是测试日期字符串是否符合预定义的日期格式。 这是一个完全不同的问题, 不能仅使用日期对象来解决。

一般来说,有几个原因; 首先,浏览器将有助于计算到正确日期的溢出月/日/时间: new Date(2012,0,290) === 2012年10月6日。

其次,因为解析器可能依赖于区域设置(mm / dd vs.dd / mm?)。 当浏览器解析日期时,我的语言环境可能会导致它将其滚动到我的时区/ DST,从而扭曲它并弄乱检测( .getDate现在可能会在第二天返回)。 更糟糕的是,这可能只发生在一年中某些时段的某些时区。

我强烈建议使用像date.js这样的库来处理这些东西,因为日期比你想象的要难得多 ! 如果你绝对必须亲自validation,那么我建议你这样详细地做:

 function isValidDate ( str ) { // parse to numbers var rm = str.split( '/' ) , m = 1 * rm[0] , d = 1 * rm[1] , y = 1 * rm[2] ; if ( isNaN( m * d * y ) ) { return false; } if ( d < 1 ) { return false; } // day can't be 0 if ( m < 1 || m > 12 ) { return false; } // month must be 1-12 if ( m === 2 ) { // february var is_leap_year = ((y % 4 === 0) && (y % 100 !== 0)) || (y % 400 === 0); if ( is_leap_year && d > 29 ) { return false; } // leap year if ( !is_leap_year && d > 28 ) { return false; } // non-leap year } // test any other month else if ((( m === 4 || m === 6 || m === 9 || m === 11 ) && d > 30) || (( m === 1 || m === 3 || m === 5 || m === 7 || m === 8 || m === 10 || m === 12 ) && d > 31)) { return false; } return true; } 

作为一个jsFiddle: http : //jsfiddle.net/3pMPp/1/
作为jsPerf: http ://jsperf.com/silly-date-valiation

这将处理实际日期,并让您有机会找到日期的哪个部分无效 – 使用日期对象

注意 :几个浏览器将愉快地解析看似无效的日期并从中创建一个日期对象。 例如,02/29/2013将解析为2013年3月1日,因此我测试在实际日期使用时输入的部件是否有意义。

DEMO

测试中

Win7的:

  • Chrome 23(只有一个在第一次约会时提供isNaN)
  • IE 9

赢得XP:

  • FX 17
  • IE 8
  • Safari 5
  • 歌剧11和12
 function isValidDateCheck(dString) { // test it is nn/nn/nnnn or nn/nn/nn var dRe = /^(\d{1,2})([\-\/])(\d{1,2})\2(\d{4}|\d{2})$/ if (!dRe.exec(dString)) { return false; } // make sure it parses as date // replace this part if you do not allow dashes dString.replace(/-/g,"/"); var date = new Date(dString); // create a date object if (!isNaN(date)) { // it may give NaN - if not test the parts var parts = dString.split("/"); // split on slash var dd = parseInt(parts[1],10); // day number var mm = parseInt(parts[0],10)-1; // month - JS months start at 0 var yyyy = parseInt(parts[2],10); // year // return true if all parts match return dd===date.getDate() && mm === date.getMonth() && yyyy===date.getFullYear(); } // here the date was not parsed as a date return false; } window.onload=function() { document.getElementById("output").innerHTML+="
12/33/2012: "+isValidDateCheck('12/33/2012'); document.getElementById("output").innerHTML+="
12/12/2012: "+isValidDateCheck('12/12/2012') ; document.getElementById("output").innerHTML+="
02/29/2012: "+isValidDateCheck('02/29/2012') ; document.getElementById("output").innerHTML+="
02/29/2013: "+isValidDateCheck('02/29/2013') ; document.getElementById("output").innerHTML+="
01/01/2013A: "+isValidDateCheck('01/01/2013A') ; }

感谢@mplungjan。 我赞成了这个答案。

@mplungjan方法(首次提出)列于http://jsfiddle.net/Lijo/uzSU6/7/ 。 这在IE8中失败了一个场景 – http://jsfiddle.net/Lijo/uzSU6/12/

所以我在引用如何validation日期之后使用了稍微不同的方法? 。 在这里查看http://jsfiddle.net/Lijo/uzSU6/20/

编辑

有关处理空格的方案,请参阅http://jsfiddle.net/uzSU6/37/

请随意用这种方法提出建议/挑战。

参考

  1. 不使用修剪检查是否存在空格
  2. 应该在JavaScript比较中使用哪个等于运算符(== vs ===)?
  3. 如何validation日期?

 function isValidDate(s) { var bits = s.split('/'); if(s.indexOf(' ') != -1) { //White space exists in the original date string return false; } //Javascript month starts at zero var d = new Date(bits[2], bits[0] - 1, bits[1]); if ( isNaN( Number(bits[2]) ) ) { //Year is not valid number return false; } if ( Number(bits[2]) < 1 ) { //Year should be greater than zero return false; } //1. Check whether the year is a Number //2. Check whether the date parts are eqaul to original date components //3. Check whether d is valid return d && ( (d.getMonth() + 1) == bits[0]) && (d.getDate() == Number(bits[1]) ); }