Got more questions? Find advice on: ASP | SQL | XML | Windows
in Search
Welcome to RegexAdvice Sign in | Join | Help

Michael Ash's Regex Blog

Regex Musings

Full Circle - JavaScript Date validation with regex

Several year ago I decided to learn Regular Expressions. I had been skimming over an article about using regex for validation on web pages. It was at least a couple of weeks before I sat down an read the article in full. After I did I wanted to try to write a regex on my one but couldn't think of anything original. Eventually I wrote a date regex that validated leap years as well, something none of the other regex I had seen at the time did. In the spirit of the article that introduced regular expressions to me I that this was something that could be used with Web Page validation. But at the time I wasn't doing a whole lot of web page development. And what little web development I was doing, didn't require me to use or validate dates.

I shared my regex on the web. I got a lot of request to do other date formats. At first I was reluctant to do that because my original pattern was troublesome to write, mostly because the text editor I was using didn't help me match parenthesis and I had a but of types to work out. Plus I always thought it would be easier to reformat the date into the format the regex was checking.

Eventually someone else reverse engineer my regex into another format. Later I wrote patterns for other formats as I saw uses beyond web page validation. I expanded the patterns as I learn more about regex. For various reasons I eventually moved away from working on these type of patterns. I had done about all I could with them. Other than fixing a bug, generally caused by a typo, I didn't do much with these patterns.

Recently I got another request for an alternate format for one of my old patterns. I referred them to my central depot of date regexes. But something else in the request reminded me of my original idea of handling other formats. So I decided to actually do it. So here it is in JavaScript

 

function isValidDate(ds, format) {
    var reDate = /^(?!(?:10([-./])(?:0?[5-9]|1[0-4])\1(?:1582)))(?:(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\2|(?:(?:0?[13-9]|1[0-2])(\/|-|\.)(?:29|30)\3))(?:(?!0000)\d{4})$|^(?:0?2(\/|-|\.)29\4(?:(?:(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:(?:\d\d)(?:[02468][048]|[13579][26]))))|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\5(?:(?!0000)\d{4}))$/;
    switch(format) {
	case "dmy":
		return reDate.test(ds.toString().replace(/(\d?\d)(\D)(\d?\d)(\D)(\d{4})/, "$3$2$1$4$5"));
	case "ymd":
		return reDate.test(ds.toString().replace(/(\d{4})(\D)(\d?\d)(\D)(\d?\d)/, "$3$2$5$4$1"));
	default:
		return reDate.test(ds);
	}
}

 

 That's it,  The function returns true or false if the string passed is a valid date.

isValidDate("11/1/2011")  // true

isValidDate("31/10/2011") // false

isValidDate("31/10/2011","dmy") // true

isValidDate("2031/10/20","ymd") // true 

The big regex is the date validator. I've talked about that enough in the past so I'm not going to go into detail about how it works just trust me that it does. Basics are 4-digits years, one or two digit months and days. You have a choice of three date separators a peiod (.), a hyphen (-) or a forward slash (/), Which ever one you chose you have to be consistent. There have been a few modifications from my original date regex to expand the time span it checks against and exclude missing day from the switch from Julian to Gregorian in 1592. but most apps won't push up against the old boundaries.

The default format checked is dd/mm/yyyy

The function take a optional second parameter that lets you specify other formats of yyyy-.mm-dd or dd-mm-yyyy but passing “ymd” or “dmy” respectively.

If the second argument is passed the given alternate format is converted to the default format for testing by the use of one of two of simple regex replace operations. Nothing really fancy The month, day and years are moved around to get to mm-dd-yyyy format.

For this I just kept it simple and handle the most common numerical date formats. For general webpage validation this function is perfectly viable. You could have taken my date regexes for all the various format and used each on base on the format. The advantage of just using one date regex is maintenance is easier. Not that the pattern needs any maintenance but if it did there is only one complex regex to deal with instead of three. Also with one regex you can't play around with other checks by using the match. I did that while playing around with this but not including that here. And while writing this I thought of a couple other things I could build off of this.

Anyway there you have it. Three regexes, one scary two simple, and a few lines of code to validate dates in 3 formats.


Sponsor
Published Tuesday, November 01, 2011 1:25 AM by mash
Anonymous comments are disabled