How to validate date using Java regular expression
My earlier post on how to validate email address, SSN and phone number validation using Java regex still attracts a lot of visitors. Today I realized that another piece of data that many programmers need to validate is the date. Many Java applications have to process input date values, so I thought it will be beneficial to this blog readers to show how regular expression can be used to validate date in Java.
First I’ll show you how to validate date using java regex in US format and later I’ll show you how that same logic can be applied to validate date in English format (used in most countries outside North America).
Let’s begin by writing the Java code to validate the date.
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegExDateValidation{ public static boolean isValidDate(String date){ boolean isValid = false; String expression = "^[0-1][1-2][- / ]?(0[1-9]|[12][0-9]|3[01])[- /]?(18|19|20|21)\\d{2}$"; /* * ^[0-1][1-2] : The month starts with a 0 and a digit between 1 and 2 * [- / ]?: Followed by an optional "-" or "/". * (0[1-9]|[12][0-9]|3[01]) : The day part must be either between 01-09, or 10-29 or 30-31. * [- / ]?: Day part will be followed by an optional "-" or "/". * (18|19|20|21)\\d{2}$ : Year begins with either 18, 19, 20 or 21 and ends with two digits. */ CharSequence inputStr = date; Pattern pattern = Pattern.compile(expression,Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(inputStr); if(matcher.matches()){ isValid = true; } return isValid; } /*Here is a simple test method to test an input date using Java regex*/ public static void main(String args[]){ boolean isValid = RegExDateValidation.isValidDate(args[0]); System.out.println(args[0] + " is " + (isValid?"valid":"invalid")); } }
I included the explanation on how the regular expression is constructed in the code, however the day part of the date needs a little more explanation.
The expression for day validation is a group of three mutually exclusive sub-expressions or alternatives. Only one of these conditions can be true. (0[1-9]|[12][0-9]|3[01]). This is done to verify that the combination of the digits in the day string falls between 01 and 31.
- The first part checks that the day has a value between 01 and 09. Therefore the expression starts
with a 0 followed by a range of digit from 1 to 9. - The second part validates the days between 10 to 29. [12] means that the first digit can be a 1 or a 2. [0-9] shows that the second digit can be any value from 0 to 9.
- The third subgroup checks for days 30 and 31.
This expression will validate dates in US format from years 1800 to 2199. For example 03/15/2009, 10/12/1885 are valid dates but the date 31/01/1999 will not pass validation. For date in European (English) format, we can rearrange the regular expression as follows.
^(0[1-9]|[12][0-9]|3[01])[- /]?[0-1][1-9][- / ]?(18|19|20|21)\\d{2,4}
Here the day comes before the month. So the date 17/08/2009 is valid but 08/17/2009 will not pass this validation. The logic is same but the elements are re-arranged. You can use following method to switch between American and English date formats dynamically at runtime based on an additional boolean parameter.
public static boolean checkDate(String date, boolean isEnglish){ String monthExpression = "[0-1][1-9]"; String dayExpression = "(0[1-9]|[12][0-9]|3[01])"; boolean isValid = false; //RegEx to validate date in US format. String expression = "^" + monthExpression +"[- / ]?" + dayExpression + "[- /]?(18|19|20|21)\\d{2}"; if(isEnglish){ //RegEx to validate date in Metric format. expression = "^"+dayExpression + "[- / ]?" + monthExpression + "[- /]?(18|19|20|21)\\d{2,4}"; } CharSequence inputStr = date; Pattern pattern = Pattern.compile(expression,Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(inputStr); if(matcher.matches()){ isValid=true; } }
Hope this is useful to all the Java developers. Share your opinions below.
Enjoy.
Ced
May 27, 2010 @ 2:21 pm
Your Date regex is incorrect; you have it set to collect months between 01-19 which isn’t valid.
it should be:
“^(0[1-9]|1[012])[- / ]?(0[1-9]|[12][0-9]|3[01])[- /]?(19|20)\d{2}$”
Regardless, great explanations. I appreciate your explanations of the email, ssn, and phone. I didn’t understand the syntax before. Now I do.
Zhahmed
October 25, 2010 @ 2:34 am
great articles and great regex CED !! Thanks
Roger
February 11, 2011 @ 7:57 am
I have been struggling with regex for a good while in one of my project, which eventually one day becoma a working spider, but to be honest I have never thought that this tool can be used for date validatin also, thanks for sharing your knowledge Zaheer
Michael
April 12, 2011 @ 2:09 pm
Bravo CED, you just saved a LOT of my time !
ch3etah
June 1, 2011 @ 3:19 pm
CED’s regex expression is OK, still doesn’t take into account the fact that 30/02/1945 is not a valid date. It’s quite complicate to verify a date as a correct one. One might use SimpleDateFormat to validate it. The problem persist as 02/02/4325 is valid and yet not a valid DOB.
Great article nonetheless, as I’m struggling with regex.
sam
August 2, 2011 @ 6:10 am
Hi,
I wonder after testing date “12/30-2011” as an argument for ur regex pattern, which is giving true as return.
ur code is right but the patten u’ve used is not absolute for date validation.
Thanks!
dean
January 20, 2012 @ 1:04 pm
Just put the limitation as:
function validate_date(date)
{
var pattern= new RegExp(“^(0[1-9]|1[012])[/]?(0[1-9]|[12][0-9]|3[01])[/]?(2012)$”);
return pattern.test(date);
}
if(!validate_date(data_date)){
alert(‘Invalid Date. Correct format is dd/mm/yyyy’);
return false;
}
so, user may type / symbol only..
meg
March 26, 2012 @ 6:58 am
What is the regex for yyyy-MM-dd’T’HH:mm:ss date format in java,
Thanks,
Meg
meg
March 26, 2012 @ 6:59 am
What is the correct date format for the string “2011-10-02T01:01:01.111-04:00” in java
Khushal
April 13, 2012 @ 8:26 am
Great explanation, however, how would it take care of wrong entry of date ?
Example
04/31/2012 (mm/dd/yyyy), it passes the regex, however the date is invalid as April only has 1 to 30 days. Also, How would it take care of non leap year date, example
02/29/2013, it passes per regexp but there is not 29th on 2013. I guess there needs to be some checking required.
Regardless, I appreciate the explanations.
Jivan
June 17, 2012 @ 7:53 am
There is another sample for Phone number and Email address validation at
http://www.thedeveloperspoint.com/?p=424