0

Is it possible to validate an regular text input as a readable date format, such as November 25, 2019? This is because I'm using a javascript date picker, however the user can still enter whatever they want.

I'm guessing this could be done use some regular expression but wondering if there is another function or solution?

I guess you could split this in 3 parts, the first part would have to be 1 of 12 month spellings, while the day would have to be 1 of 31 followed by a comma and then the year would have to validate as something between 1000 & 9999.

So far this is where I'm headed

var dateval = $('#' + formId + ' input[name=date]').val();
var res = dateval.split(" ",3);
var d1 = res[0];
var d2 = res[1];
var d3 = res[2];

var montharray = ['Januaray','February'];
var dayarray = ['1,','2,'];

if($.inArray(d1,montharray) !== -1){
    alert('good month');
}       
if($.inArray(d2,dayarray) !== -1){
    alert('good day');
}
drooh
  • 578
  • 4
  • 18
  • 46
  • It would be very hard to make something like that foolproof. – Examath Nov 02 '19 at 04:50
  • well I'm working on it and I don't think it would be to hard. I can use php however Id like to do this upfront before the form is submitted. – drooh Nov 02 '19 at 04:51
  • Generally, it's only possible to reliably validate a date string if you know the format of the string. Otherwise, you're just guessing. E.g. 04/03/02 could be one of at least 3 different dates, all valid, at least two of which are wrong (and that doesn't count less common formats). – RobG Nov 04 '19 at 13:27

3 Answers3

0

why not when user loses the focus from the date picker, fire an event which will the take the user input of the date and do the following -

var dateEntered = // add the date entered by the user 

var date = new Date(dateEntered); // this will make sure to convert the date entered by the user into a valid date

if it is wrong date then date would have some error i hope you can figure that out

i hope it helps

  • That won't tell you if the date is valid. To check if the date is valid: https://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript – kmoser Nov 02 '19 at 04:55
  • Your code is not valid Javascript. Also, checking for a [truthy](https://stackoverflow.com/questions/35642809/understanding-javascript-truthy-and-falsy) value simply doesn't work, since an invalid date will be seen as truthy. – kmoser Nov 02 '19 at 05:15
  • See [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) This answer assumes that anything the built–in parser can parse must be a valid date, which is wrong. It also infers all implementations will return the same result for a given string, which is also wrong. – RobG Nov 04 '19 at 13:24
0

You can validate and interpret dates quite easily, as long as you tell the user your format. You don't need a list of days or years, just a list of month abbreviations and lengths:

var d;

function val() {
  var s = document.getElementById("i").value;
  s = s.trim(); //Remove some fustration:
  s = s.replace(/[.,/\-]/g," ");
  s = s.replace(/\s\s+/g, ' '); 
  var a = s.split(" ");  
  var day = Number(a[1]);
  var smonth = a[0].substr(0,3).toLowerCase();
  var month = 13;
  for (var i = 0; i < 12; i++) {
    if (smonth == Months[i].name) {
      month = i;
      break;
    }
  }
  year = Number(a[2]);
  if (isBtwn(month, 0, 11) && isBtwn(year, 1900, 2100) && isBtwn(day, 1, monthL(month, year))) {
    d = new Date(Number(year), Number(month), Number(day));
    document.getElementById("o").innerHTML = "Valid: " + d.toDateString();
  } else document.getElementById("o").innerHTML = "Not valid";
}

function isBtwn(val, min, max) {
  if (val >= min && val <= max) return true;
}

function monthL(m,y) {
  l = Months[m].length;
  if (m == 1) {
    if (y % 400 == 0) l++;
    else if (y % 4 == 0 && y % 100 != 0) l++;
  }
  return l;
}

var Months = [{
    name: "jan",
    length: 31
  },
  {
    name: "feb",
    length: 28
  },
  {
    name: "mar",
    length: 31
  },
  {
    name: "apr",
    length: 30
  },
  {
    name: "may",
    length: 31
  },
  {
    name: "jun",
    length: 30
  },
  {
    name: "jul",
    length: 31
  },
  {
    name: "aug",
    length: 31
  },
  {
    name: "sep",
    length: 30
  },
  {
    name: "oct",
    length: 31
  },
  {
    name: "nov",
    length: 30
  },
  {
    name: "dec",
    length: 31
  }
]
<p>Use format <code>Month DD YYYY:</code></p>
<input id="i" oninput="val()" />
<div id="o"></div>

If you can convert a string into a date, you've validated it. (You might as well send the data as three numbers, not as a string). There are a few things to consider when creating this kind of converter, like:

  • Typing out an entire month is hard, and if there are spelling errors, it can become frustrating. Checking the first three characters, using .substr(0,3) of a month is enough.
  • Leap years (extra day in February every 4 years, but not 100 years, but every 400 years) need to be included.
  • It shouldn't be case sensitive for convenience, which can be achieved by running .toLowerCase()
  • Using .replace(/[.,/\-]/g," ") converts some characters used to space the day, month and year with uniform spaces, improving compatibility
  • Using .replace(/\s\s+/g, ' ') removes sequential spaces, improving it's tolerance to simple typos.

It is possible to have multiple formats; just have multiple validators, each designed for a different format, in a sequence.

Examath
  • 176
  • 9
  • So your formats DD Month YYYY? Yeah, it's possible, hovever, you only need two arrays: All the months, and the lengths of each month. – Examath Nov 02 '19 at 23:53
  • Format changed. – Examath Nov 04 '19 at 07:23
  • If the question is "how to validate a date", then there are already [many such questions and plenty of answers](https://stackoverflow.com/search?q=%5Bjavascript%5D+how+to+validate+a+date), most very much shorter than this one. – RobG Nov 04 '19 at 13:36
0

This will validate date in this format Fullmonth day, YYYY

function validate_date(dateval){

    var valid = true;
    var res = dateval.split(" ",3);
    var d1 = res[0];
    var d2 = res[1];
    var d3 = res[2];

    var montharray = ['Januaray','February','March','April','May','June','July','August','September','October','November','December'];
    var dayarray = ['1,','2,','3,','4,','5,','6,','7,','8,','9,','10,','11,','12,','13,','14,','15,','16,','17,','18,','19,','20,','21,','22,','23,','24,','25,','26,','27,','28,','29,','30,','31,'];
    var leapyears = ['2020','2024','2028','2032','2036','2040','2044','2048','2052','2056','2060','2064','2068','2072','2076','2080','2084','2088','2092','2096'];

    if($.inArray(d1,montharray) === -1){
        valid = false;
    }   
    if($.inArray(d2,dayarray) === -1){
        valid = false;
    }
    if(d3 < 1000 || d3 > 9999){
        valid = false;
    }
    if(d1 == 'February' && d2 == '30,'){
        valid = false;
    }
    if(d1 == 'February' && d2 == '31,'){
        valid = false;
    }
    if(d1 == 'April' && d2 == '31,'){
        valid = false;
    }
    if(d1 == 'June' && d2 == '31,'){
        valid = false;
    }
    if(d1 == 'September' && d2 == '31,'){
        valid = false;
    }
    if(d1 == 'November' && d2 == '31,'){
        valid = false;
    }
    if(d1 == 'February' && d2 == '29,'){
        if($.inArray(d3,leapyears) === -1){
            valid = false;
        }
    }
    return valid;
}
drooh
  • 578
  • 4
  • 18
  • 46