Link to home
Start Free TrialLog in
Avatar of richardsimnett
richardsimnett

asked on

Regex to match Date?

Hello,
Im trying to write a regex to match a date to a string. The regex should return true for the following exampels:

1/1/1990
01/01/1990
1/1/90
01/01/90
1/1/90 hh:mm:ss
hh:mm: ss 1/1/90
01/01/90 hh:mm:ss
hh:mm: ss 01/01/90

Or any combination of the above. Basically I need to make sure that the string matches this

<any characters> ##/##/####</any characters>

Can someone give me the regex to do this? I cant seem to figure it out.


Worth 500 points.

Thanks,
Rick
public boolean isValidDate(String date)
    {
        final String RE_DATE = ""; //What goes in the "s?
        return date.matches(RE_DATE);
    }

Open in new window

Avatar of javaexperto
javaexperto
Flag of Mexico image

Do you want to match only that date?  01/01/1990
Or do you want to  match all valid dates?
try this,

            String pattern = "(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])/(19|20)\\d\\d" ;
            String date = "01/01/1990" ;
            System.out.println( date.matches( pattern ) ) ;
Avatar of CEHJ
Try
RE_DATE = "\\d{1,2}/\\d{1,2}/\\d{4}|\\d{1,2}/\\d{1,2}/\\d{2}(?: \\d{2}:\\d{2}:\\d{2})?|\\d{2}:\\d{2}: \\d{2} \\d{1,2}/\\d{1,2}/\\d{2}";

Open in new window

Avatar of richardsimnett
richardsimnett

ASKER

javaexperto,
No it just must match a date string format ##/##/#### or #/#/## or combinations thereof.
ksisavanth,
that always returns false. I am testing with these dates, 1/1/01, 01/01/2001, 1/1/2001, 01/01/01.

Heres what I have:

 public boolean isValidDate(String date)
    {
        final String RE_DATE =  "(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])/(19|20)\\d\\d";
        return date.matches(RE_DATE);
    }

Thanks,
Rick
cehj,
That pattern doesnt work either.

Thanks,
Rick
Works fine for me. All the expected results here:
public class Dates {
    public static void main(String[] args) {
	String[] DATES = {
	    "1/1/1990",
	    "01/01/1990",
	    "1/1/90",
	    "01/01/90",
	    "1/1/90 11:11:11",
	    "11:11: 11 1/1/90",
	    "01/01/90 11:11:11",
	    "11:11: 11 01/01/90"
	};
	//I am testing with these dates, 1/1/01, 01/01/2001, 1/1/2001, 01/01/0
	String[] DATES2 = {
	    "1/1/01",
	    "01/01/2001",
	    "1/1/2001",
	    "01/01/0"
	};
 
	final String RE = "\\d{1,2}/\\d{1,2}/\\d{4}|\\d{1,2}/\\d{1,2}/\\d{2}(?: \\d{2}:\\d{2}:\\d{2})?|\\d{2}:\\d{2}: \\d{2} \\d{1,2}/\\d{1,2}/\\d{2}";
 
	for(int i = 0;i < DATES.length;i++) {	
	    if (!(DATES[i].matches(RE))) {
		System.out.printf("No match for date %s\n" , DATES[i]);
	    }
	    else {
		System.out.printf("Date %s matches\n", DATES[i]);
	    }
	}
	for(int i = 0;i < DATES2.length;i++) {	
	    if (!(DATES2[i].matches(RE))) {
		System.out.printf("No match for date %s\n" , DATES2[i]);
	    }
	    else {
		System.out.printf("Date %s matches\n", DATES2[i]);
	    }
	}
    }
}

Open in new window

CEHJ,
Here is my test output:

Comparing 01/01/09
Result: true
DATE: true
Comparing 01/01/2009
Result: true
DATE: true
Comparing 1/31/2009
Result: true
DATE: true
Comparing 1/31/2009 11:11:11
Result: false
DATE: false
Comparing 1/31/2009 11:11
Result: false
DATE: false
Comparing 1/1/2009 11:11
Result: false
DATE: false


This is my function:

 public boolean isValidDate(String date)
    {
        final String RE = "\\d{1,2}/\\d{1,2}/\\d{4}|\\d{1,2}/\\d{1,2}/\\d{2}(?: \\d{2}:\\d{2}:\\d{2})?|\\d{2}:\\d{2}: \\d{2} \\d{1,2}/\\d{1,2}/\\d{2}";
        System.out.println("Comparing " + date);                
        System.out.println("Result: " + date.matches(RE));
        return date.matches(RE);
    }

It seems to match the date fine, and that is all it needs to do, it just must match that a date formatted as above occurs in the string. The time and stuff is neither here nor there. It may or may not be there. The issue occurs when the time is included.

Thanks,
Rick
>>The time and stuff is neither here nor there. It may or may not be there. The issue occurs when the time is included.
>>

are you going to just chheck if the pattern matches or going to extract the match from a string?

as per you question, you told that you just want to match! if so, you need not check the time part at all as that may or not exist but you want allways expect the valid date!
>>The time and stuff is neither here nor there. It may or may not be there.

You should have said that earlier! I was simply going on the info i had at the time. In fact the whole thing's a lot easier if you're not interested in the time. I would recommend you extract the date as it would be poor design not to and to find later that you need it. Very little extra work for the engine
>>that always returns false. I am testing with these dates, 1/1/01, 01/01/2001, 1/1/2001, 01/01/01.

try this,

public boolean isValidDate(String date)
    {
        final String RE_DATE =  "(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])/(19|20)?\\d\\d";
        return date.matches(RE_DATE);
    }
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
On 2nd thoughts, the result of that wouldn't be clear, so it would be better to use Matcher.find and return null if not found
Using an optimised version of k's RE (since it's tighter than mine) see below. Just test for null until you're interested in the date
import java.util.regex.Pattern;
import java.util.regex.Matcher;
 
public class DateValidator {
    final static Pattern RE_DATE =  Pattern.compile("((?:0?[1-9]|1[012])/(?:0?[1-9]|[12][0-9]|3[01])/(?:19|20)?\\d\\d)");
 
    public static String getValidDate(String input) {
	Matcher m = RE_DATE.matcher(input);
	return m.find()? m.group(1) : null;
    }
}

Open in new window

ksi,
That regex doesnt seem to work too well. It fails when it hits the time tests again.

Thanks,
Rick
use matched.find() instead of string.matches()!
cehj,
Actually the field is already a known date field, the purpose of this function is simply to validate that there is a valid date in there. This is part of a web app, which accepts data in, validates it, and then stores it into the database.

This works great:

.*?(\\d{1,2}/\\d{1,2}/\\d{2,4}).*

Thanks!




Can you show what happened when you tried the code at http:#24166235 ? i.e. input, output, expected output