Search code examples
javatimetime-format

Java - 12 H to 24 Hour Format (hackerrank)


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

Convert 12 hours to 24 hours

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);
    }
}

Solution

  • 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