0

Below is the regex I am have:

Pattern ddpat = Pattern.compile( "(\\d{1,2}/\\d{1,2}/\\d{4})" );

For an invalid date pattern 02/29/1975 (Since it is not a leap year), when I try the above REGEX on this invalid date, I don't want my REGEX to match this invalid date.

Please suggest is there some way to achieve this.

WhoAmI
  • 819
  • 4
  • 18
  • 35
  • 3
    that is not possible with Regex, you have to code these type validations – Dalorzo Jul 30 '14 at 16:52
  • 2
    There is simply no answer to this question – laune Jul 30 '14 at 16:55
  • Theoretically (!!!) you can create a regular expression enumerating (!!!) all valid dates, with factoring to reduce repetitions, (stopping today or at some point in the future). This will be a big regex, but it would be a "way to achieve this". (THIS IS NOT MEANT SERIOUSLY.) – laune Jul 30 '14 at 16:57
  • 2
    Regex is the wrong tool for this job (checking validity of dates). The issue is not only with leap year, this regex will accept: `99/99/9999` as well ;) – Nir Alfasi Jul 30 '14 at 16:58
  • I agree with this. But since this is an existing code working for years in production, I won't be able to change it any way, hence just trying to do something and let it work as of now. – WhoAmI Jul 30 '14 at 17:00
  • Check this [answer](http://stackoverflow.com/questions/8647893/regular-expression-leap-years-and-more/24390306#24390306); the regex there has a range from 1000 to 2999, validates leap years and optionally the time part – hex494D49 Jul 30 '14 at 17:05

1 Answers1

2

You will have to use DateFormatter in order to validate dates.

Not only that, you will have to set the DateFormat's setLenient to false in order to catch those kinds of errors

public static void main(String[] args) throws ParseException {
    String d = "02/29/1975";
    DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
    sdf.setLenient(false);
    Date date = sdf.parse(d);
    System.out.println(date);
}

You will see that it throws the ParseException

If you don't set up the leniency, then the DateFormat will attempt to parse it to a convenient albeit arbitrary Date for example:

02/29/1975 could be converted to 03/01/1975

gtgaxiola
  • 9,241
  • 5
  • 42
  • 64
  • I am having an array of Date format something like this:DateFormat[] format = new DateFormat[]{ new SimpleDateFormat("MM/dd/yyyy"), new SimpleDateFormat("dd/MM/yy") }; In this case, how to use the setLenient ? – WhoAmI Jul 30 '14 at 16:58
  • @WhoAmI loop over your format array and setLenient(false); before you use it – gtgaxiola Jul 30 '14 at 16:59
  • Rather than looping, is there any shortcut so that I can set it while declaring the array? I just want to optimize the code. Please suggest. – WhoAmI Jul 30 '14 at 17:01
  • I believe by default DateFormat has leniency set to true... So I don't know if there's a way to overload it on construction. – gtgaxiola Jul 30 '14 at 17:02
  • 1
    @WhoAmI seriously, is a three line code (if you separate the braces) `for(DateFormat f : format) { f.setLenient(false);}` – gtgaxiola Jul 30 '14 at 17:04
  • Ok fine...have to take it. Now it the parsing fails, I am getting an exception: `ava.text.ParseException: Unparseable date: "02/29/1975"`. I dont want to throw an exception but rather return the date itself. Can you please suggest how to avoid throwing exception? – WhoAmI Jul 30 '14 at 17:10
  • 1
    Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58377/discussion-between-gtgaxiola-and-whoami). – gtgaxiola Jul 30 '14 at 17:12