# AM/PM to 24 hour time conversion

I recently joined the website www.hackerrank.com for programming challenges, and one of them was a time conversion from 12 hour to 24 hour. Rather than using the Date class, I decided to write the code for it, and in the end I came up with this:

String time = new Scanner(System.in).nextLine();
String suffix = time.substring(time.length()-2);
time = time.replace(suffix, "");
String[] hms = time.split(":");
if (suffix.equals("PM")) {
hms[0] = String.valueOf(Integer.parseInt(hms[0])+12);
hms[0] = hms[0].equals("24") ? "12" : hms[0];
}
else if (suffix.equals("AM")) {
hms[0] = hms[0].equals("12") ? "00" : hms[0];
}
System.out.println(String.join(":", hms));


And the code passed all the test cases proposed by the website. Is there any way that my code can be improved?

• Do something about invalid input? Also, splitting at a particular position is a bit error-prone. – Ian May 18 '16 at 14:34
• @Ian Excluding error checking. It's pretty simple to check the input format, would only need a simple regex and if it doesn't match throw an exception. Looking for input on the algorithm only – Shadow May 18 '16 at 14:37

It's not clear how many digits the output is supposed to have. For midnight, you output "00", but for 1 am to 9 am, you echo the hour, which may or may not have a leading zero.

Taking the last two characters as the suffix, then doing time.replace(suffix, ""), feels like a fragile operation. Consider treating this as a pattern-matching exercise instead, and using a regular expression. Since the pattern also describes the valid input strings, you get input validation for free.

private static final Pattern TIME12 = Pattern.compile(
"(?<h>0?\\d|11|12):(?<ms>[0-5]\\d:[0-6]\\d)\\s*(?<ampm>[AP]M)"
);

public static String time24(String time12) {
Matcher m = TIME12.matcher(time12);
if (!m.matches()) throw new IllegalArgumentException();

int h = "12".equals(m.group("h")) ? 0 : Integer.parseInt(m.group("h"));
if ("PM".equals(m.group("ampm"))) h += 12;
return String.format("%02d:%s", h, m.group("ms"));
}


### Variable assignment

time = time.replace(suffix, "");
String[] hms = time.split(":");


You can inline both steps so that you don't need to reassign time.

### Logic

Error checking aside, since you don't actually need to parse the non-hour components, you can likely just extract the hour part out:

String hour = time.substring(0, 2);
if (time.endsWith("PM")) {
hour = /* ... */ ;
} else {
hour = /* ... */ ;
}
System.out.println(hour + time.substring(2, time.length() - 2));


### Validation and unit testing

Thought it might still be helpful to point this out, even though you're hand-waving it away. :)