java.time
Is there any particular reason why are you using the troublesome and long outdated SimpleDateFormat
class? Your best first step would be to throw it out. Instead use LocalTime
and DateTimeFormatter
from java.time
, the modern Java date and time API. That API is much nicer to work with.
There are basically two ways to go about your problem. I will present them in turn using java.time
.
Option 1: look at the string and decide its format
Make a simple test to determine which format to use; for example, if the string ends in M
, use ha
, otherwise Hmm
.
private static DateTimeFormatter formatterWithAmPm
= DateTimeFormatter.ofPattern("ha", Locale.ENGLISH);
private static DateTimeFormatter formatterWithMinutes
= DateTimeFormatter.ofPattern("Hmm");
public static LocalTime parseTime(String inputTime) {
if (inputTime.endsWith("M")) {
return LocalTime.parse(inputTime, formatterWithAmPm);
} else {
return LocalTime.parse(inputTime, formatterWithMinutes);
}
}
I was frankly surprised to see that format pattern string Hmm
parses 123
as 01:23 and 1234
as 12:34, but it’s very convenient.
I think this option lends itself best to few constant formats. It wouldn’t be too easy to extends with further formats at a later time.
Option 2: try all relevant formats until one works
Try each possible format in turn, catch any exception and see which one doesn’t throw any.
private static final DateTimeFormatter[] parseFormatters
= Arrays.asList("ha", "Hmm") // add more format pattern strings as required
.stream()
.map(fps -> DateTimeFormatter.ofPattern(fps, Locale.ENGLISH))
.toArray(DateTimeFormatter[]::new);
public static LocalTime parseTime(String inputTime) {
DateTimeParseException aCaughtException = null;
for (DateTimeFormatter formatter : parseFormatters) {
try {
return LocalTime.parse(inputTime, formatter);
} catch (DateTimeParseException dtpe) {
aCaughtException = dtpe;
// otherwise ignore, try next formatter
}
}
throw aCaughtException;
}
Take care to check if you have two formats that may match the same input and yield different results. This also means that you cannot distinguish all thinkable formats in this way. It’s not too unreasonable to imagine a format where 1300
means minute 1300 of the day, that is 21:40. It could even mean second 1300 of the day, 00:21:40.