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

时间:2012-12-14 12:16:02

标签: javascript jquery

我已经尝试了Detecting an "invalid date" Date instance in JavaScript的两个热门答案来检查有效日期。我在IE8中对它们进行了测试 - 不幸的是两者都令人失望。在此处查看http://jsfiddle.net/Lijo/uzSU6/2/

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

注意:令我惊讶的是,它在Firefox中也不能很好用......

CONDITION

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

enter image description here

CODE

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/

3 个答案:

答案 0 :(得分:7)

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

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

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

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

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

我强烈建议您使用像date.js这样的库来处理这些内容,因为dates are much harder than you think!如果你绝对必须亲自验证,那么我建议你这样做:

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

答案 1 :(得分:2)

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

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

DEMO

经过测试

  

Win7:

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

Win XP:

     
      
  • FX 17
  •   
  • IE 8
  •   
  • Safari 5
  •   
  • Opera 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') ;
}

答案 2 :(得分:1)

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

@mplungjan方法(首次建议)列在http://jsfiddle.net/Lijo/uzSU6/7/中。 IE8在一个场景中失败了 - http://jsfiddle.net/Lijo/uzSU6/12/

所以我在引用How to validate a date?后使用了稍微不同的方法。在此处查看http://jsfiddle.net/Lijo/uzSU6/20/

修改

请参阅http://jsfiddle.net/uzSU6/37/了解处理空格的方案

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

<强>参考

  1. Check whether white spaces exist without using trim
  2. Which equals operator (== vs ===) should be used in JavaScript comparisons?
  3. How to validate a date?
  4. <强> CODE

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