Reputation: 9146
User gives me a String that should represent expire date with the format of "yyyy-mm-dd".
I want to validate whether it's a date or not, and that's how I do it:
try {
DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
System.out.println("Validating " + date + " as date");
df.parse(date);
}
catch (ParseException ex) {
// not yyyy-mm-dd date.
System.out.println(": Bad");
out.println(date + " cannot be parsed as a date. format: yyyy-mm-dd.");
return;
}
If user gives me "2014-02-02gy."
,
Then it prints: "Validating 2014-02-02gy. as date"
i.e. exception has not been thrown.
Why? and how can I validate a date? Thanks in advance.
EDIT: Used regular expression as one of the comentters suggestion:
if (!date.matches("\\d{4}-\\d{2}-\\d{2}") {
out.println("Not a date");
}
Upvotes: 2
Views: 5795
Reputation:
Since DateFormat strangely matches only the start of the string (seems like a bug for me but it's documented, so well..), I'd explicitly add an end delimiter, like this
DateFormat df = new SimpleDateFormat("yyyy-mm-dd,");
String date = "2014-02-02,";
System.out.println("Validating " + date + " as date");
df.parse(date);
Upvotes: 0
Reputation: 7241
If you are not committed to use Java standard libraries, take a look at Joda-Time. The library is much more evolved than standard Java Dates. The piece of code for your case becomes as easy and clean as:
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
...
try {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
System.out.println("Validating " + date + " as date");
formatter.parseDateTime(date);
} catch (IllegalArgumentException e) {
System.out.println(": Bad");
System.out.println(date + " cannot be parsed as a date. format: yyyy-mm-dd.");
return;
}
...
On the other hand, if you have to stick to standard Java, I would go for ns47731's or Chris Gerken's solutions (which are roughly equivalent, my preference for Chris but that is personal taste).
Upvotes: 1
Reputation: 9146
I used the following regular expression in order to validate a date:
if(!date.matches("\\d{4}-\\d{2}-\\d{2}") {
out.println("Not a date");
}
Thanks for everyone that commented or answered :)
Upvotes: 0
Reputation: 11440
From the doc of DateFormat.parse
* Parses text from the beginning of the given string to produce a date.
* The method may not use the entire text of the given string.
* <p>
* See the {@link #parse(String, ParsePosition)} method for more information
* on date parsing.
*
* @param source A <code>String</code> whose beginning should be parsed.
* @return A <code>Date</code> parsed from the string.
* @exception ParseException if the beginning of the specified string
* cannot be parsed.
"if the beginning of the specified string cannot be parsed." - it parses from the start until it gets the date it needs. So the gy
is removed from the example you showed.
To fix:
String date = "2014-02-02gy";
try {
DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
System.out.println("Validating " + date + " as date");
Date dateObject = df.parse(date);
if(!df.format(dateObject).equals(date))
throw new ParseException(date, 0);
} catch (ParseException ex) { // not yyyy-mm-dd date.
System.out.println(": Bad");
System.out.println(date + " cannot be parsed as a date. format: yyyy-mm-dd.");
return;
}
Upvotes: 3
Reputation: 16392
You could always reverse the parse with a format to see if what you end up with is what you started with.
DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
String after = df.format(df.parse(date));
if (after.equals(date)) {
// validated
}
Upvotes: 5
Reputation: 279910
Note the javadoc of SimpleDateFormat#parse(string)
which says
The method may not use the entire text of the given string.
I don't believe you will be able to validate the characters at the end of your String
this way. Note that the date is valid. You just want to check that a String matches a certain pattern.
Upvotes: 1