Проверка Javascript Valid Date не работает в IE8 (и Firefox)

Я пробовал два популярных ответа из Обнаружение "недопустимой даты" . Дата экземпляра в JavaScript для проверки действительных дат. Я тестировал их обоих в IE8. К сожалению, оба разочаровывают. См. Здесь http://jsfiddle.net/Lijo/uzSU6/2/

Есть ли лучший JavaScript-код, который будет работать в IE8 + Chrome + Firefox?

Примечание. К моему удивлению, в Firefox тоже плохо работает...

УСЛОВИЕ

Предполагается, что формат даты будет форматом даты США с косой чертой (/)

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/.

Ответы

Ответ 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/ к сценариям, которые обрабатывают пробелы

Не стесняйтесь предлагать свои предложения/задачи с помощью этого подхода.

Ссылки

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

} 

Ответ 2

Вы, кажется, объединяете две вещи здесь. Допустимые даты и допустимые даты. Это не та же проблема.

Вопрос, на который вы ссылались, отвечает на вопрос, как проверить достоверность даты объектов (является ли объект даты экземпляром "неверная дата" ). Недействительные объекты даты генерируются при использовании недопустимых параметров при их создании: new Date('?')

Вы хотите проверить, соответствует ли строка даты предопределенному формату даты. Это совершенно другая проблема, которая не должна решаться с использованием только объектов даты.

Вообще говоря, для этого есть несколько причин; во-первых, браузеры будут полезно вычислять переполнения месяцев/дней/времени до нужной даты: new Date(2012,0,290) === 06 октября 2012 года.

Во-вторых, потому что парсер может быть зависим от локали (мм/дд против дд/мм?). Когда дата анализируется браузером, мой язык может привести к тому, что он перевернет его в мой часовой пояс /DST, таким образом, перевернув его и испортив обнаружение (.getDate теперь может вернуться на следующий день). Хуже того, это может произойти только в некоторых часовых поясах в определенные части года.

Я настоятельно рекомендую использовать библиотеку, например date.js, чтобы обрабатывать этот материал, потому что даты намного сложнее, чем вы думаете! Если вы обязательно должны подтвердить это вручную, я рекомендую сделать это подробно следующим образом:

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

Ответ 3

Это приведет к фактическим датам и даст вам возможность определить, какая часть даты была недействительной - с помощью DATE OBJECT

ПРИМЕЧАНИЕ: несколько браузеров с удовольствием проанализируют то, что кажется неверной датой, и сделайте из него объект даты. Например, 02/29/2013 будет анализироваться с 1 марта 2013 года, поэтому мой тест, чтобы увидеть, были ли введенные части полезными, когда они используются в фактическую дату.

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