1
\$\begingroup\$

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?

\$\endgroup\$
1
\$\begingroup\$

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"));
}
\$\endgroup\$
0
\$\begingroup\$

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. :)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.