Note : I looked as much as I could for 2 days to check if this is a duplicate. If I missed something, I apologize. This question is to find what the issue is with my attempt at a solution, not one of the existing solutions out there.
My Question
I was trying to solve some problems on hackerrank in Java 7 and I came across the time conversion problem where the problem statement is:
Problem: "Given a time in -hour AM/PM format, convert it to military (24-hour) time."
Sample Input 07:05:45PM
Sample Output 19:05:45
I looked at solutions involving libraries (such as java.text.SimpleDateFormat, Calendar etc.) but I am trying to do it on my own without them. The issue that I am facing here is that my solution is failing on some test cases but is working on others. In short, it is not the correct solution. I see other solutions but I want to know why mine fails as the correct answer. Could you please help me by telling me where this would fail and how I can go about correcting it?
Some of the solutions that I looked at are:
Conversion from 12 hours time to 24 hours time in java
My code is here:
import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;
public class Solution {
static String timeConversion(String s) {
//get the string into an array using : as a separator
String[] time_array = s.split(":");
//military_time variable to be returned
String military_time = new String();
//final HH part
String hh_final = new String();
//Rest after HH to be concatenated to get military_time
String rest = new String();
StringBuilder REST_mil_builder = new StringBuilder();
for (int i = 2; i < 8; i++) {
REST_mil_builder.append(s.charAt(i));
}
//"rest" basically gets everything after HH excluding AM/PM, so 01:03:40PM would have a "rest" value of ":03:40"
rest = REST_mil_builder.toString();
int hh = Integer.parseInt(time_array[0]);
String AMPM_contains = time_array[2];
//converting if the last piece after the split contains "PM"
if (AMPM_contains.contains("PM")) {
hh = hh + 12;
hh = hh == 24 ? 0 : hh;
}
//converting hh to have a 0 before it because when it is an integer 01 will be just 1 which we don't want
StringBuilder hh_build = new StringBuilder();
if (hh >= 0 && hh <= 9) {
hh_build.append("0");
hh_build.append(hh);
hh_final = hh_build.toString();
} else {
hh_build.append(hh);
hh_final = hh_build.toString();
}
//military time concatenation
military_time = hh_final + rest;
//Midnight is 12:00:00AM on a 12-hour clock, and 00:00:00 on a 24-hour clock
military_time = s == "12:00:00AM" ? "00:00:00" : military_time;
//Noon is 12:00:00PM on a 12-hour clock, and 12:00:00 on a 24-hour clock.
military_time = s == "12:00:00PM" ? "12:00:00" : military_time;
return military_time;
}
private static final Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
//tried several 12 hour time formats here
String result = timeConversion("01:30:59PM");
System.out.println(result);
}
}
Your code fails because it doesn't correctly handle hour 12, i.e. 12:xx:xxAM
should map to 00:xx:xx
, and 12:xx:xxPM
should map to 12:xx:xx
, as pointed out in answer by Ole V.V.
Rather than trying to fix the overly complicated code you have, here is a different approach, without using SimpleDateFormat
.
Parse the first 2 digits to a number. If the number is 12, set it to 0. A trick way to do that is to use modulo 12. If input ends with PM
, add 12. Now rebuild string, replacing first 2 digits with new number, and removing AM/PM suffix.
Like this:
public static String timeConversion(String s) {
int hour = Integer.parseInt(s.substring(0, 2)) % 12;
if (s.endsWith("PM"))
hour += 12;
return String.format("%02d", hour) + s.substring(2, 8);
}
Using tests by Ole V.V.
System.out.println(timeConversion("12:30:59AM"));
System.out.println(timeConversion("11:30:59AM"));
System.out.println(timeConversion("12:30:59PM"));
System.out.println(timeConversion("11:30:59PM"));
Output
00:30:59
11:30:59
12:30:59
23:30:59