Wednesday, June 20, 2007

Java regex matching date

I found many resources on the web give really weak regular expression for date matching. The best I found is this. However, I found some example of pretty horrible regex for matching date in Java.

For example, to match a date of 25/05/2007 (dd/mm/2007).
  1. \\d\\d-\\d\\d-\\d\\d\\d\\d
  2. \\d{2}-\\d{2}-\\d{4}
While these may work, but it won't be accurate. What is needed is:

(0[1-9]|[1-9]|[12][0-9]|3[01])-(0[1-9]|1[012]|[1-9])-(19|20)\\d{2}


(0[1-9]|[1-9]|[12][0-9]|3[01])
This will make sure that date is within range from 1 to 31.

(0[1-9]|1[012]|[1-9])
Similarly matches against month from 1-12 or 01-12

(19|20)\\d{2}
And of course year to be a valid 19** or 20**.

9 comments:

Anonymous said...

what about thinks like 29 february ? or is month have 30 or 31 days ? you can do it if you really want to in regex, but should you ?

Seymour Cakes said...

Well, it's not perfect but it's way way more effective matching than blind numeric match.

IMHO, yes you should.

Anonymous said...

Thanks, nice regex!

Anonymous said...

I like it :-) Added some checks in between numbers to deal with peoples crazy ways of dating things. With the following pattern:

(0[1-9]|[1-9]|[12][0-9]|3[01])[\\-/.]?(0[1-9]|1[012]|[1-9])[\\-/.]?(19|20)?\\d{2}

You can enter
1.1.09
1/1/09

Anonymous said...

Woops, took out the wrong character. Should have been:
(0[1-9]|[1-9]|[12][0-9]|3[01])[ \\-/.](0[1-9]|1[012]|[1-9])[ \\-/.](19|20)?\\d{2}

also supports
1 1 09

joao said...

Ok, here it goes a possible version to check february. But after this you still have to verify if february has 28 or 29 days.

(19|20)\\d{2}-(((0[13456789]|1[012])-([0-3][0-1]|[0-2][0-9]))|((02-([0-2][0-9]))))

To check february, we could use:

Calendar cal=Calendar.getInstance();
cal.set(year,month-1,28);
call.add(5,1); // Adds a day
if (call.get(5)==1)
System.out.println("28 days");
else
System.out.println("29 days");

Regards,
Joao

Anonymous said...

you have a nice site. thanks for sharing this site. there are various kinds of ebooks are available here

http://feboook.blogspot.com

Anonymous said...

mpsahtek for the regex!
Thanks!

Anonymous said...

By far the best regular expression for dates is

^(?=\d)(?:(?!(?:(?:0?[5-9]|1[0-4])(?:\.|-|\/)10(?:\.|-|\/)(?:1582))|(?:(?:0?[3-9]|1[0-3])(?:\.|-|\/)0?9(?:\.|-|\/)(?:1752)))(31(?!(?:\.|-|\/)(?:0?[2469]|11))|30(?!(?:\.|-|\/)0?2)|(?:29(?:(?!(?:\.|-|\/)0?2(?:\.|-|\/))|(?=\D0?2\D(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:(?:\d\d)(?:[02468][048]|[13579][26])(?!\x20BC))|(?:00(?:42|3[0369]|2[147]|1[258]|09)\x20BC))))))|2[0-8]|1\d|0?[1-9])([-.\/])(1[012]|(?:0?[1-9]))\2((?=(?:00(?:4[0-5]|[0-3]?\d)\x20BC)|(?:\d{4}(?:$|(?=\x20\d)\x20)))\d{4}(?:\x20BC)?)(?:$|(?=\x20\d)\x20))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2}(?:\x20[aApP][mM]))|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2})?$


This handles leap years and all manner of validation