4

我已经尝试了两个流行的答案,来自Detecting an "invalid date" Date instance in JavaScript for checks valid dates。我在 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/

4

3 回答 3

8

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

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

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

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

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

我强烈建议使用date.js 之类的库来处理这些东西,因为日期比你想象的要难得多!如果您绝对必须手动验证,那么我建议您像这样详细地进行验证:

function isValidDate (str) {
  // parse to numbers
  const rm = str.split('/');
  const m = 1 * rm[0];
  const d = 1 * rm[1];
  const y = 1 * rm[2];
  if (isNaN(m * d * y)) {
    return false;
  }
  // day can't be 0
  if (d < 1) {
    return false;
  }
  // month must be 1-12
  if (m < 1 || m > 12) {
    return false;
  }
  // february
  if (m === 2) {
    const isLeapYear = ((y % 4 === 0) && (y % 100 !== 0)) || (y % 400 === 0);
    // leap year
    if (isLeapYear && d > 29) {
      return false;
    }
    // non-leap year
    if (!isLeapYear && d > 28) {
      return false;
    }
  }
  // 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

于 2012-12-15T23:56:59.827 回答
3

这将处理实际日期,并让您有机会找到日期的哪一部分无效 - 使用DATE OBJECT

注意:一些浏览器会很乐意解析似乎无效的日期并从中生成一个日期对象。例如,2013 年 2 月 29 日将解析为 2013 年 3 月 1 日,因此我测试了输入的部分在实际日期中使用时是否有意义。

演示

经测试

赢7:

  • Chrome 23(只有一个在第一次约会时给出 isNaN)
  • 即 9

赢经验:

  • 外汇 17
  • 即 8
  • 野生动物园 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+="<br/>12/33/2012: "+isValidDateCheck('12/33/2012');
  document.getElementById("output").innerHTML+="<br/>12/12/2012: "+isValidDateCheck('12/12/2012') ;
  document.getElementById("output").innerHTML+="<br/>02/29/2012: "+isValidDateCheck('02/29/2012') ;
  document.getElementById("output").innerHTML+="<br/>02/29/2013: "+isValidDateCheck('02/29/2013') ;
  document.getElementById("output").innerHTML+="<br/>01/01/2013A: "+isValidDateCheck('01/01/2013A') ;
}
于 2012-12-14T12:35:25.507 回答
1

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

@mplungjan 方法(第一个建议)列在http://jsfiddle.net/Lijo/uzSU6/7/中。对于一种情况,这在 IE8 中失败了 - http://jsfiddle.net/Lijo/uzSU6/12/

因此,在参考了如何验证日期之后,我使用了稍微不同的方法?. 在这里看到它http://jsfiddle.net/Lijo/uzSU6/20/

编辑

处理空格的场景请参考http://jsfiddle.net/uzSU6/37/

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

参考

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

代码

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]) );

} 

​</p>

于 2012-12-14T14:35:43.743 回答