SO: Test a date string

by Michel Plungjan

HTML

<div id="main">
<p>This will handle actual dates and give you the chance to find what part of the date was invalid - using the <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date">DATE OBJECT</a></p>

<p><b>NOTE:</b> several browsers will happily parse what seems to be an invalid date and make a date object out of it. <br/>For example 02/29/2013 will parse as 1st of March 2013, hence my test to see if the parts entered made sense when used in an actual date.</p>


<div id="output"></div>
    <hr/>
<p><b>Tested in</b>

<ul>
  <li>Win7:
    <ul>
      <li>Chrome 23 (only one to give isNaN on the first date)</li>
      <li>IE 9</li>
    </ul> 
  </li>        
  <li>Win XP:
    <ul>
      <li>FX 17</li>
      <li>IE 8</li>
      <li>Safari 5</li>
      <li>Opera 11 and 12</li>
    </ul>
  </li>        
</ul>           
</p>
</div>










<script>

/* by: thinkingstiff.com license: http://creativecommons.org/licenses/by-nc-sa/3.0/us/ */
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-28096782-1']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
    
var headerUri = 'http://stackoverflow.com/a/13878816/295783',
    headerCaption = '<div style="padding-top:5px">Javascript Valid Date Checking does not work in IE8 (and Firefox)</div>';
document.body.insertAdjacentHTML(
    'afterBegin',
      '<a href="' + headerUri + '" '
    + 'target="_top" '
    + 'onmouseover="this.style.opacity=\'.95\'" '
    + 'onmouseout="this.style.opacity=\'1\'" '
    + 'style="'
        + 'background-color: grey;'
        + 'background-image: linear-gradient( top, rgba( 255, 255, 255, .3), rgba( 255, 255, 255, 0) );'
        +...

CSS

#main { padding:3px }
.passed { color:green }
.failed { color:red }
.pre { font-family:monospace }

JavaScript

function isValidDateCheck(dString) {
    var dRe = /^(\d{1,2})([\-\/])(\d{1,2})\2(\d{4}|\d{2})$/
        
    if (!dRe.exec(dString)) {
      console.log(dString, " was not correct format");
      return false; 
    }   
    
    dString.replace(/-/g,"/"); // make sure it parses as date - replace this part if you do not allow dashes
    
    var date = new Date(dString); // create a date object
    console.log(dString,date);
    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
    console.log(dString,"gave isNaN")
    return false;
}
var tests = [
    {d:"12/33/2012",a:false},
    {d:"12/12/2012",a:true},
    {d:"02/29/2012",a:true},
    {d:"02/29/2013",a:false},
    {d:"01/01/2013A",a:false},
    {d:"01/     01        /2013",a:false}
    ];
window.onload=function() { doTest(tests)};
    
// ---------------- ignore the rest of the page --------------
// test function - 
function doTest(arr) {
  for (var i=0;i<arr.length;i++) {
    var d=arr[i].d;
    var a=arr[i].a;  
    var html="<br/><span class='pre "+(a?"passed":"failed")+"'>"+d+"</span>: "+
        (a===isValidDateCheck(d)?"<span class='passed'>("+a+")</span>":"<span class='failed'>failed</span>");
      document.getElementById("output").innerHTML+=html;     
  }
}    

    
    if (!window.console) window.console={ log:function(str) {alert(str)}};