Reputation: 5478
I have the following bit of Java code:
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
Date date;
try {
date = df.parse(userString);
} catch (ParseException e) {
date = df.parse("07/12/2016 01:00");
LOGGER.error("Could not parse date, reverting to default");
}
So, what I'm trying to do is to parse the user input as a date and, if that fails, to replace it with a default date.
However, the second df.parse()
requires a try-catch of its own, even though that's a value I know for certain will work. It doesn't make any sense for the second parse
not to work and if it indeed doesn't, I have nothing more to do, I might as well terminate the program because the world has ended. :)
Is there a way to avoid the need for a second try-catch
block?
Upvotes: 1
Views: 5612
Reputation: 2778
You say it doesn't make sense to have the second try-catch. this is half true. yes, you are saying it wont fail but Java doesn't know this.
You could pre-parse a single default date reference, store is as a class member, and return that (but you'd still need a try catch on that - and it's not immutable).
There is nothing wrong with trying to reduce the lines of code. There are several answers to this question which give you work arounds for no try-catch but I think these make the code less clear and more error prone over all. There are schools of thought such as to avoid state flags, avoid nullable values, don't reassign variables etc.
I would just use a nested try-catch in this case and move on with your life. It's a little but ugly, but safer and clearer than than other approaches.
So while this isn't an answer to your question, I'm posting this is an answer because I think answering the question makes your code worse overall. :)
This is how I would write the function for best readability, maintainability and safety...
public Date parseDate(String userString) {
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
try {
return df.parse(userString);
} catch (ParseException e) {
LOGGER.error("Could not parse date '" + userString + "' reverting to default");
try {
return df.parse("07/12/2016 01:00");
} catch (ParseException shouldntHappen) {
throw new RuntimeException(shouldntHappen);
}
}
}
Upvotes: 4
Reputation: 44414
The correct way to create a specific date is with the existing date-time classes:
LocalDateTime local = LocalDateTime.of(2016, 7, 12, 1, 0);
ZonedDateTime zoned = ZonedDateTime.of(local, ZoneId.systemDefault());
date = Date.from(zoned.toInstant());
You can also use Calendar. If you’re using a version of Java older than Java 8, Calendar is the only way to do it:
Calendar calendar = Calendar.getInstance();
calendar.set(2016, Calendar.JULY, 12, 1, 0, 0);
date = calendar.getTime();
Caution: Calendar.JULY is not equal to 7. Use the month constants to avoid errors.
Upvotes: 0
Reputation: 5625
If your default date is predetermined, meaning if you don't have to parse it, you can just use
date = new Date(1468285200L * 1000); // unix time * 1000(milliseconds)
Otherwise just use SimpleDateFormat.parse(String text, ParsePosition pos)
like this;
date = df.parse("07/12/2016 01:00", new ParsePosition(0));
Which does not throw any ParseException
but returns the date or null
based on whether parsing was successful.
Upvotes: 2
Reputation: 22462
You can avoid nested try
as shown below by setting the default date in the finally
block by checking for isError
flag to true
upon ParseException
:
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
Date date1;
Date date2;
boolean isError = false;
try {
date1 = df.parse("07/12/2016 01:00");
date2 = df.parse(userString);
} catch (ParseException e) {
isError= true;
LOGGER.error("Could not parse date, reverting to default");
} finally {
if(isError) {
date2 = date1;
}
}
Upvotes: 2
Reputation: 74
ParseException is checked exception. So you have to write it in try catch block or in method declaration just write throws PraseException. But then your calling method has to catch the exception. There is no other way to avoid checked exceptions
Upvotes: -1
Reputation: 44854
I would move this functionality to a method, which can then be re-used
public static void main (String [] args)
{
Date dt = setDate ("07/12/2016 x1:00");
if (dt == null) {
dt = setDate ("07/12/2016 01:00");
}
System.out.println(dt);
}
private static Date setDate(String in) {
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy mm:HH");
Date date = null;
try {
date = df.parse(in);
} catch (ParseException e) {
System.out.println("Could not parse date, reverting to default");
}
return date;
}
Upvotes: 2