2

I have a date in string format YYYY/MM/DD HH:MM:SS which I need to validate using preconditions google guava class. I am using checkArgument method in lot of other places. How can I use checkArgument method to validate startDate to make sure it is in this format only YYYY/MM/DD HH:MM:SS and if they are not, then throw IllegalArgumentException with some message.

public Builder startDate(String startDate) {
    // validate startDate here using checkArgument if it is not valid then throw IllegalArgumentException.
    this.sDate = startDate;
    return this;
}

How can I use checkArgument method here?

user1950349
  • 4,738
  • 19
  • 67
  • 119

3 Answers3

2

Don't. Write

 try {
   new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(startDate);
 } catch (ParseException e) {
   throw new IllegalArgumentException(e);
 }

..which will also let you store the Date parsed and use it later. (Though, to be fair, java.util.Date is a terrible API best avoided -- but you implied you were using it in a previous question you appear to have deleted.)

If you end up using Joda Time, http://joda-time.sourceforge.net/userguide.html#Input_and_Output explains how to adjust this answer for those needs.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • Note that by default, `SimpleDateFormat` instances are _lenient_ w.r.t. parsing input strings. So, unless you want to allow date strings such as `2015/13/32 25:60:60` to parse correctly, you should call [`setLenient(false)`](https://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#setLenient%28boolean%29) on the `SimpleDateFormat` instance before parsing. – Mick Mnemonic Jan 09 '16 at 02:02
1

The Answer by Louis Wasserman is correct. He mentions avoiding the java.util.Date.

java.time

That java.util.Date class, and its partner java.util.Calendar, have been supplanted in Java 8 and later by the java.time framework. See the Oracle Tutorial.

We use DateTimeFormatter and DateTimeParseException classes instead. Contained in the java.time.format package.

Here is the equivalent of his Answer using java.time classes.

try {
    DateTimeFormatter.ofPattern ( "yyyy/MM/dd HH:mm:ss" ).parse ( input );
} catch ( e ) {
    throw new DateTimeParseException ( e );
}

Joda-Time

For those unable to move to Java 8 or later, add the Joda-Time library to your project. Joda-Time provided the inspiration for java.time, and the two frameworks share the same concepts.

Wasserman’s same logic applies to our solution: Make a parse attempt, and catch an exception. We use the DateTimeFormatter class from Joda-Time which throws a standard Java IllegalArgumentException when encountering bad input.

try {
    DateTimeFormatter formatter = DateTimeFormat.forPattern ( "yyyy/MM/dd HH:mm:ss" );
    DateTime dt = formatter.parseDateTime ( input );
} catch ( e ) {
    throw new IllegalArgumentException ( e );
}
Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • I am on Java 7 as of now so can't use Java 8. :( – user1950349 Jan 09 '16 at 00:34
  • 1
    @user1950349 I would strongly advise using third-party libraries like Joda Time over `java.util.Date` if you can _possibly_ manage it. – Louis Wasserman Jan 09 '16 at 00:42
  • @LouisWasserman I can manage that but then will it change anything in the parsing logic you have? – user1950349 Jan 09 '16 at 00:43
  • @user1950349, sure, you'll have to use Joda's APIs for that then. http://joda-time.sourceforge.net/userguide.html#Input_and_Output explains all the details there. – Louis Wasserman Jan 09 '16 at 00:44
  • 1
    As Wasserman says, the old date-time classes really are so bad that they should be avoided. Add and use the [Joda-Time](http://www.joda.org/joda-time/) library instead. In using Joda-Time, follow the same logic seen in Wasserman’s Answer: call on a date-time formatter instance to attempt a parse, and catch the parsing exception. – Basil Bourque Jan 09 '16 at 00:45
  • That sourceforge.net URL in the comment above is out of date. See the [Getting Started](http://www.joda.org/joda-time/quickstart.html) and [User Guide](http://www.joda.org/joda-time/userguide.html) pages for Joda-Time. Joda-Time provided the inspiration for java.time, so by learning Joda-Time you will be learning the basic concepts that can be applied to mastering java.time later in the future. – Basil Bourque Jan 09 '16 at 00:47
  • @user1950349 Yes, bingo. I added that Answer’s code snippet to my Answer here in a new "Joda-Time" section. – Basil Bourque Jan 09 '16 at 00:58
0

You can test the whole string against a regular expression:

Preconditions.checkArguments(str.matches(VALID_DATE_REGEX));

To speed things up, you can compile the Pattern once and invert the call

Preconditions.checkArgument(VALID_DATE_REGEX.matcher(str).matches());

However this is a smell. You should not carry this string of text back and forth in your program: if you need that format it's just because at some point you'll convert it to a date. So you'd better decide if your program can accept invalid input and reporting it to the user, or if it should terminate immediately.

The latter is easier to handle: parse the text immediately and throw an exception for invalid input. Otherwise you need to introduce a validation step in your program, and then program a way to stop the flow and showing the user any blocking and non-blocking errors in the input.

Raffaele
  • 20,627
  • 6
  • 47
  • 86