Click here to Skip to main content
15,887,485 members
Articles / Programming Languages / Javascript
Tip/Trick

JavaScript Date Validation

Rate me:
Please Sign up or sign in to vote.
4.93/5 (17 votes)
29 Nov 2012CPOL1 min read 224.5K   22   30
JavaScript Date Validation
For a few days now, I have been battling with the problem of JavaScript date validation. I wanted to validate text inputed by a user as they were typing to tell them if it was a valid date. After much searching on the internet, I found nothing that worked. So I wrote the following code to do the job, it is a simple but effective isDate function:
 
C#
//Value parameter - required. All other parameters are optional.
function isDate(value, sepVal, dayIdx, monthIdx, yearIdx) {
    try {
        //Change the below values to determine which format of date you wish to check. It is set to dd/mm/yyyy by default.
        var DayIndex = dayIdx !== undefined ? dayIdx : 0var MonthIndex = monthIdx !== undefined ? monthIdx : 0;
        var YearIndex = yearIdx !== undefined ? yearIdx : 0;
 
        value = value.replace(/-/g, "/").replace(/\./g, "/"); 
        var SplitValue = value.split(sepVal || "/");
        var OK = true;
        if (!(SplitValue[DayIndex].length == 1 || SplitValue[DayIndex].length == 2)) {
            OK = false;
        }
        if (OK && !(SplitValue[MonthIndex].length == 1 || SplitValue[MonthIndex].length == 2)) {
            OK = false;
        }
        if (OK && SplitValue[YearIndex].length != 4) {
            OK = false;
        }
        if (OK) {
            var Day = parseInt(SplitValue[DayIndex], 10);
            var Month = parseInt(SplitValue[MonthIndex], 10);
            var Year = parseInt(SplitValue[YearIndex], 10);
 
            if (OK = ((Year > 1900) && (Year < new Date().getFullYear()))) {
                if (OK = (Month <= 12 && Month > 0)) {

                    var LeapYear = (((Year % 4) == 0) && ((Year % 100) != 0) || ((Year % 400) == 0));   
                    
                    if(OK = Day > 0)
                    {
                        if (Month == 2) {  
                            OK = LeapYear ? Day <= 29 : Day <= 28;
                        } 
                        else {
                            if ((Month == 4) || (Month == 6) || (Month == 9) || (Month == 11)) {
                                OK = Day <= 30;
                            }
                            else {
                                OK = Day <= 31;
                            }
                        }
                    }
                }
            }
        }
        return OK;
    }
    catch (e) {
        return false;
    }
} 
 
Just copy the above function and call isDate(value) where value is a string containing a valid or invalid date. The function returns a bool true if the string was a date and false if it wasn't. Hope this helps! Smile | <img src= " />
 
EDIT: Thanks to Member 2792937 for bringing a bug to my attention.
 
Both parseInt('08') and parseInt('09') return zero because the function tries to determine the correct base for the numerical system used. In JavaScript, numbers starting with zero are considered octal and there's no 08 or 09 in octal, hence the problem.
 
To fix this, just add the second parameter for parseInt, the base to be used for the conversion. The correct calls should be parseInt('08', 10) and parseInt('09', 10).

(From http://www.ventanazul.com/webzine/articles/issues-parseint-javascript[^])
 
I have modified my code to fix this issue.

EDIT: Now includes optional parameters for specifying separator value and the indexes. To miss out a parameter simply pass in undefined. Thanks to Lester Callif for the suggestions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
BugDefault day, month, year indexes will not work. Also, param sepVal is not working properly. Pin
Min Htun Zaw5-Oct-13 0:51
Min Htun Zaw5-Oct-13 0:51 
SuggestionNewer version Pin
Master DJon5-Dec-12 6:24
Master DJon5-Dec-12 6:24 
GeneralRe: Newer version Pin
joni8a5-Mar-13 3:30
joni8a5-Mar-13 3:30 
AnswerRe: Newer version Pin
Master DJon5-Mar-13 7:10
Master DJon5-Mar-13 7:10 
AnswerRe: Newer version Pin
Master DJon5-Mar-13 8:55
Master DJon5-Mar-13 8:55 
QuestionShorter code Pin
redphx4-Dec-12 20:13
redphx4-Dec-12 20:13 
QuestionAlternative to parseInt() Pin
Daniel Trott4-Dec-12 6:03
Daniel Trott4-Dec-12 6:03 
QuestionImpressive, but have a couple of mods that should take care of both the date format and the separator for diff countries. Pin
Lester Callif27-Nov-12 15:46
Lester Callif27-Nov-12 15:46 
AnswerRe: Impressive, but have a couple of mods that should take care of both the date format and the separator for diff countries. Pin
Ed Nutting29-Nov-12 10:52
Ed Nutting29-Nov-12 10:52 
GeneralRe: Impressive, but have a couple of mods that should take care of both the date format and the separator for diff countries. Pin
Lester Callif29-Nov-12 12:50
Lester Callif29-Nov-12 12:50 
AnswerRe: Impressive, but have a couple of mods that should take care of both the date format and the separator for diff countries. Pin
Ed Nutting30-Nov-12 9:16
Ed Nutting30-Nov-12 9:16 
Yeah sure I can Smile | :)

So when developing a small web application it is very easy to copy/paste code from one place to another and just make sure later that you change all the copies if you ever want to change something. This is made much easier by the fact that there is probably only a development team of < 5 people. However, inconsistency issues can arise if this technique is used when scaling up. For instance, if you take on a new member of staff, say someone from Europe for example. Now all of your code may be programmed using the traditionally British style of dd/mm/yyyy but your new European employee may use mm.dd.yyyy. If you set that new employee on a programming task and they forget (as they likely will) that the British standard should be used, you have immediately built in an inconsistency into your web application (which clearly is bad from a UI point of view and for data checking/verification). Furthermore, if the code is then copied around the place, a larger development team will rapidly lose track of where all the copies of the date checking code calls are and thus if you change to a different date format you can't guarantee you have changed all your code! Sigh | :sigh: A final problem is that say you wanted to run two versions of your site, one for Europe one for UK. Naturally you want to make as few changes as possible or even run the site as one website with automatic detection of where a request is coming from. If you have copied calls to isDate all over the place specifying different date formats for each call you will have yourself an all mighty mess trying to convert it for the new site.

So why is having one call with few parameters, and have defaults built in to the isDate function, better?
- If you change format, you change the code in one place and have site-wide results in seconds.
- If you want to build in request location detection, you can do it simply in the isDate function - one change, one place, very easy.
- If a developer new to the code needs to change something in the date validation, they only need to change it in one place and do not need to check every call to isDate to check that nothing is broken/unexpected or worse still, needs redoing.

So clearly in bigger applications it becomes more sensible to copy as little as possible and have it all in one place. If you did want to separate out the date format from the date validation, it should be done by creating a new method/JS file to contain one set of code for doing the format checking and that new code should be called from one place (in the isDate cycle) - from within isDate, not by methods calling isDate else you'd be back to the problem of duplicated code Smile | :)

Hope explains things well enough,
Ed
AnswerRe: Impressive, but have a couple of mods that should take care of both the date format and the separator for diff countries. Pin
Ed Nutting29-Nov-12 11:01
Ed Nutting29-Nov-12 11:01 
QuestionJust one bug in February Pin
Member 324090521-Nov-12 12:37
Member 324090521-Nov-12 12:37 
AnswerRe: Just one bug in February Pin
Ed Nutting25-Nov-12 11:09
Ed Nutting25-Nov-12 11:09 
QuestionDesign flaw in your code Pin
Member 942879613-Sep-12 13:38
Member 942879613-Sep-12 13:38 
AnswerRe: Design flaw in your code Pin
Ed Nutting13-Sep-12 20:26
Ed Nutting13-Sep-12 20:26 
BugYear Validation Pin
XtremLucky24-Apr-12 3:05
XtremLucky24-Apr-12 3:05 
GeneralRe: Year Validation Pin
Ed Nutting24-Apr-12 6:16
Ed Nutting24-Apr-12 6:16 
GeneralRe: Year Validation Pin
greg_ryan17-Jul-12 12:54
greg_ryan17-Jul-12 12:54 
GeneralMinor Bug Fix for the non-slash people... Pin
Ed Nutting13-Mar-12 12:11
Ed Nutting13-Mar-12 12:11 
GeneralI am *very* surprised that none of our North American friend... Pin
Peter_in_278026-Sep-11 16:15
professionalPeter_in_278026-Sep-11 16:15 
GeneralRe: Yes I guess that is a little surprising. But then again, I w... Pin
Ed Nutting26-Sep-11 20:19
Ed Nutting26-Sep-11 20:19 
GeneralReason for my vote of 5 found to be complete, simple and ele... Pin
rquadros25-Jul-11 12:34
rquadros25-Jul-11 12:34 
QuestionBug with year validation Pin
Member 842090121-Nov-11 5:59
Member 842090121-Nov-11 5:59 
AnswerRe: Bug with year validation Pin
Ed Nutting21-Nov-11 9:42
Ed Nutting21-Nov-11 9:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.