6

I can't quite figure out how to validate a date input type in javascript. I tried looking on the internet but I just couldnt find anything.

I have one field that ask the user to input its birthday. I want to validate it in javascript with the certain limits on days months and, especially years. For example if the user input more than 2016(or the current year) it would give an error. I can't quite figure out how to "extract" the date input type and control every elements of it (day, month, year).

Here part of my html

<form method="POST" action="request.jsp" onsubmit="return validate()">
Date of birth: <input type="date" id="bday" name="bday" value="">
</form>

Javascript:

var birthday = document.getElementById('bday').value;

This is all i've got.. please help?

shean
  • 93
  • 1
  • 2
  • 8

7 Answers7

4

TLDR

You have to parse the string as a date (JavaScript provides the Date API for this very use case).

Full answer

You're on the right track. Here's a JSBin example I did. Try opening the console and changing the date, and you'll see it logged.

$('#birthday').on('change', function() {
   console.log(new Date(this.value));
});

(I'm using jQuery in the above example just for convenience sake, but you can use whatever you want.)

The problem you have here is that the date is logged as a string. You can use the JavaScript Date object to parse the string.

Based on whatever validation you want to do, you can use various date object methods (like getFullYear, for example) and match those against the input.

I'll leave the full implementation up to you, but the inside of the change handler might look like:

var date = new Date(this.value);

if(date.getFullYear() > 2016) {
  // do something (like show a message, for example)
}
Josh Beam
  • 19,292
  • 3
  • 45
  • 68
  • Thanks for the answer, i noticed you used jQuery but i'm a beginner and i haven't looked into it.. – shean Mar 15 '16 at 00:12
  • @shean You don't need to use jQuery. In the example, I'm just selected a DOM node (in this case, the element with `birthday` as the ID) and watching its `onchange` event. Are you familiar with JavaScript events? – Josh Beam Mar 15 '16 at 00:13
  • he's got an onsubmit attr in the `
    `
    –  Mar 15 '16 at 00:17
  • @JoshBeam yes i am but i'm not familiar with jQuery syntax, anyway i understood your code and what you were trying to say (sorta) – shean Mar 15 '16 at 00:26
  • 1
    No, don't do that. An input type date will return a string like "2016-03-20". The Date constructor (and Date.parse) will parse that as UTC, so for users west of Greenwich the resulting local date will be "2016-03-19". **Always** manually parse date strings, a library can help but is rarely necessary. – RobG Mar 15 '16 at 00:41
3

if you're simply trying to validate whether or not a string is a valid date, you can just check that it creates a valid date object.

function isValidDate(d){
    return !isNaN((new Date(d)).getTime());
}

https://jsfiddle.net/46cztok6/


so your validate() function would look like this.

function validate(){
    var birthday = document.getElementById('bday').value;
    if(!isValidDate(birthday)){
        alert("you did not enter a valid birthday");
        return false;
    } 
}
  • I wanna validate if the date is valid – shean Mar 15 '16 at 00:21
  • that's exactly what this does. –  Mar 15 '16 at 00:42
  • The *isValidDate* function can be simply `return !isNaN(new Date(d));`. However, you are also relying on the Date constructor to correctly pasre the string, something that is it notoriously bad at doing (even if fully compliant with ECMAScript 2015). – RobG Mar 15 '16 at 00:50
  • sure but manually parsing a date string (or anything, really) for ambiguous formats is tedious and difficult to do flawlessly. this way works for 95+% of real world applications. –  Mar 15 '16 at 01:10
  • 3 lines of code to [*parse and validate a date string*](http://stackoverflow.com/questions/5812220/how-to-validate-a-date/5812341#5812341) in a way that works in every user agent that supports javascript is hardly tedious. The above will fail in a lot more than 5% of cases. – RobG Mar 15 '16 at 02:25
  • @RobG those three lines will validate a single date format, hardly ambiguous. i am not sure why you believe that 5% of browsers don't support the Date object but i personally doubt that's true. –  Mar 15 '16 at 03:20
2

If you are able to get the value of the input element with:

 var birthday = document.getElementById('bday').value;

Then birthday will be available to you as a string (all input values are always returned to JavaScript as strings). From there, you'd need to convert that string to a date with:

 var dob = Date.parse(birthday);

Then, once you've got the entire date, you can extract the pieces of it with the various JavaScript Date/Time methods:

 var month = dob.getMonth(); // months start counting from zero!
 var day   = dob.getDate();
 var year  = dob.getFullYear();  // getYear() provides 3 digit year!

Here's a working example:

var birthday = null, btn = null, output = null;

// Wait until the document is ready for interaction:
window.addEventListener("DOMContentLoaded", function(){

     // Get references to DOM elements needed:
     birthday = document.getElementById('bDate');
     btn = document.getElementById('btnGetDate');
     output = document.getElementById('result');


     // Set up an event callback for when the button gets clicked:      
     btn.addEventListener("click", function(){
       

        // Create a new Date that converts the input date
        var dob =new Date(birthday.value);
        alert(dob);

        // Extract pieces of the date:
        var month = dob.getMonth(); // months start counting from zero!
        var day   = dob.getDate();  
        var year  = dob.getFullYear();

        // Now that you have the pieces of the date, you can validate as you wish:
        // e.g. if(year > 2016) { . . . }
  
        // Write out date:
        output.innerHTML = ++month + "/" + ++day + "/" + year; 

     });
  
});





  
<input type="date" id="bDate">
<input type="button" id="btnGetDate" value="Get Date">
<p id="result"></p>

NOTE: Keep in mind that Daylight Savings Time will have an effect on the result depending on what time of day it is. See: How to check if the DST (Daylight Saving Time) is in effect and if it is what's the offset? for more info. on that.

Community
  • 1
  • 1
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • How does daylight saving affect parsing of a date string? Where in the world does changing into or out of the daylight saving zone affect the date? When I select 7 March, why does your code show 8 March (hint: you're probably west of Greenwich so have used `++day`, I'm east). – RobG Mar 15 '16 at 01:26
  • You are correct. What I meant (but didn't articulate well) was that the UTC offset is affected by DST. I am -5:00 GMT normally, but as of yesterday, while I'm still in that zone, it's actually -4:00. – Scott Marcus Mar 15 '16 at 01:53
  • I have a submit button on the form, what is that get button for? – shean Mar 15 '16 at 09:58
  • My example just shows how to work with a date field and I needed a button to activate the function. You would use your button. – Scott Marcus Mar 15 '16 at 16:30
2

Input type date is not supported in all browsers, so you should detect that and replace the input with a suitable alternative that includes the format that is required.

Where supported, the input will return an ISO 8601 format date string without a time zone. According to ISO 8601, this should be treated as local, but TC39 in their wisdom decided that it should be treated as UTC, so that is what Date.parse (and the Date constructor) will do in most cases. In some it will be treated as local and in IE 8 as invalid. So for systems with a timezone that is west of Greenwich, Date.parse('2016-03-20') will return a Date object that, when displayed as a local date, will be '2016-03-19', i.e. one day early.

So you should manually parse the date string, validate the date using one of the many answers here, then check whether the year, month and day are within your constraints.

Community
  • 1
  • 1
RobG
  • 142,382
  • 31
  • 172
  • 209
  • not necessary to detect and replace the date input type as it falls back to the default text type on browsers that don't support it. also, your link doesn't work. –  Mar 15 '16 at 01:12
  • @yourmom—link fixed. How do you suppose users will behave given a date input field with zero help on the format expected? Simply replacing it with a text input is not sufficient, hence "*…suitable alternative **that includes the format that is required***". – RobG Mar 15 '16 at 02:23
  • that's exactly the point of the question. if a user's browser supports the date picker it's already going to be a valid date. it's not necessary to tell someone to label their inputs, isn't that sort of given.. –  Mar 15 '16 at 03:17
  • @yourmom—no it's not. The question only asks about input type date. I'm trying to point out that a significant number of users have browsers that don't support it, so something suitable has to be offered instead. A plain text field is not sufficient unless the OP is happy for those users to guess the format required. Doing what the OP requires doesn't even require parsing the value to a Date. – RobG Mar 15 '16 at 03:37
  • op expressed interested in manipulating the date, ie month, year. this will absolutely require the Date object. the date object accepts ambiguous formats. there is no reason to tell a user to put it in a specific way. –  Mar 15 '16 at 03:56
  • @yourmom—"*the date object accepts ambiguous formats*" you mean parsing is unreliable. What date does 12/06/09 represent? Which browsers will fail to parse "2016-03-20"? Which will treat "2016-03-20T00:00:00" as UTC and which as local? Which treat "2016/20/03" as invalid and which as "2017-08-03"? Or " "2016-13-20 00:00:00"? The vagaries are legion, please do not recommend leaving it to the parser, which, per the specification, is almost entirely implementation dependent (and they all differ in some or many ways). – RobG Mar 15 '16 at 04:32
  • fair enough. from a programming perspective i can understand why you'd want to dictate a format, however from a ux perspective once might consider letting the user enter an ambiguous format and then verify the date in a fixed, verbose format. –  Mar 15 '16 at 05:07
1

Here is a bin so you can have an idea how to start validating this type of field: https://jsbin.com/lifacaxonu/edit?html,js,console,output

$('#birthday').on('change', function() {
  var val = this.value.split('-');
  if (val[0] > new Date().getFullYear()) {
    console.log('invalid')
  } else {
    console.log('ok')
  }
});
vbotio
  • 1,566
  • 3
  • 26
  • 53
0

After looking out for 3 hours, i wrote this and achieved dd/mm/yyyy date input using plain Javascript.

<div class="container">
        <div class="datetime-container">
            
            <input type="text" placeholder="write your date" id="datetime" onblur="validateDate()">
            <p id="error"></p><br>
            <input type="tel" maxlength="10" placeholder="dd/mm/yyyy"
    oninput="this.value = DDMMYYYY(this.value, event)" />     
        </div>

    </div>
    <script>
        function DDMMYYYY(value, event) {
          let newValue = value.replace(/[^0-9]/g, '').replace(/(\..*)\./g, '$1');
        
          const dayOrMonth = (index) => index % 2 === 1 && index < 4;
        
          // on delete key.  
          if (!event.data) {
            return value;
          }
          let currentYear = new Date().getFullYear();
          console.log(newValue.slice(2,4));
          if(newValue.length>=2 && newValue.slice(0,2)>31){
              tempValue = newValue;
              newValue = tempValue.replace(tempValue.slice(0,2),31);
              
            document.getElementById("error").style.display = "initial";
            document.getElementById("error").innerHTML = "Invalid day!";
          }else if(newValue.length>=4 &&newValue.slice(2,4)>12){
            document.getElementById("error").style.display = "initial";
            document.getElementById("error").innerHTML = "Invalid month!";
            tempValue = newValue;
            newValue = tempValue.replace(tempValue.slice(2,4),12);
          }else if(newValue.length==8 && newValue.slice(4)>currentYear){
            tempValue = newValue;
            newValue = tempValue.replace(tempValue.slice(4),currentYear);
            document.getElementById("error").style.display = "initial";
            document.getElementById("error").innerHTML = "Invalid year!";
          }
          else{
            document.getElementById("error").style.display="none";
          }
          return newValue.split('').map((v, i) => dayOrMonth(i) ? v + '/' : v).join('');;
        }
        </script>
0
var dob=new Date(birthdate.value);
var month,day,year;

month=dob.getMonth();
day=dob.getDate();
year=dob.getFullYear();

if(birthdate.value == ""){
    alert("Birth Date is Required");
}
if(year > 2023 && month >= 2){
    alert("Birth Date is Invalid");
}
  • It's good to approach into more of abstraction creating such a example. Worth to stop using `var` anymore. – devzom Mar 28 '23 at 09:30