0

I am writing a program that takes a users input for hours and minutes in the format HH:MM, and returns a string of that input. For example, 13:56 would be "four minutes to two".

I have created the code to do exactly that - take the input in that format and return a value as above. My issue is that I am not sure how to handle errors. I have a while loop that is meant to catch errors but it doesn't. I mainly want to ensure that if the user enters a character input (ee:rb or 12:bb etc.) or an invalid time (14:68 (I am going on a 12 hour clock)), that the program says "Error!" and makes the user try again.

I have worked with exception handling, but have not done so for SimpleDateFormat and I can't figure out why the below does not work.

  • `if (timeToString != simpFormat.format(d).toString())` → This will fail. See https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java/513839. – VGR Nov 26 '18 at 15:04
  • Thank you. Yes I have removed that as well as my while loop, and am now using a do loop. I am still getting an error though. – Luke Byrne Nov 26 '18 at 15:05

2 Answers2

0

Given that you are just expecting a simple string hh:mm, I might use String#matches here:

do {
    timeToString = in.nextLine();
} while (!timeToString.matches("(1[0-2]|0[1-9]):[0-5]\\d"));

This above loop will iterate until the users enters a valid 12 hour hour:minute string. If you don't like this approach, another approach would be to use SimpleDateFormat#parse to attempt to parse the input. This method throws a ParseException, so you could try catching and looping on that.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • Thank Tim. Can I ask, where would you add this? Instead of both my If and While loop? Also I did try something similar but kept getting the error "Invalid escape sequence" which is why I abandoned it. – Luke Byrne Nov 26 '18 at 14:59
  • The above three lines are intended to replace your "safety net" while loop. – Tim Biegeleisen Nov 26 '18 at 15:00
  • Thanks Tim. I am still getting the invalid escape sequence error, which I am unsure of how to fix. – Luke Byrne Nov 26 '18 at 15:03
  • @LukeByrne I had a small typo in my original post, `\d` for `\\d`. You might have to reload your page. – Tim Biegeleisen Nov 26 '18 at 15:11
  • Thanks again Tim - It's still not working for me after reformatting the Do loop. I'm not exactly sure why, but thanks for your help. I replaced the if and while loop with the do loop, but just get an error message when testing for the wrong input. – Luke Byrne Nov 26 '18 at 15:25
  • If you can create a demo and paste the link here, I'm happy to have a look. – Tim Biegeleisen Nov 26 '18 at 15:29
  • Thanks Tim. I have re-edited the code above to reflect my changes. – Luke Byrne Nov 26 '18 at 15:36
0

Try this:

public static void main(String[] args) {
    boolean safetyNet = false;
    Scanner in = new Scanner(System.in);
    Date d = new Date();
    SimpleDateFormat simpFormat = new SimpleDateFormat("hh:mm");

    while (!safetyNet) {
        System.out.println("Please enter the time in hours and minutes: ");
        String timeToString = in.next();
        try {
            d = simpFormat.parse(timeToString);
            safetyNet = true;
            String sHours = timeToString.substring(0, 2);
            String sMinutes = timeToString.substring(3);
            int hours = Integer.parseInt(sHours);
            int minutes = Integer.parseInt(sMinutes);
            String time=getTimeName(hours, minutes);
            if(time.isEmpty()){
                safetyNet = false;
            }else{
                System.out.printf("Time is: " + getTimeName(hours, minutes));
            }   
        } catch (ParseException e) {
            System.out.println("Error! Try again: ");
            // e.printStackTrace();
        }
    }
    in.close();
}

public static String getTimeName(int hours, int minutes) {
    String timeName = "";

    if (hours >= 1 && hours <= 12 && minutes >= 0 && minutes <= 59) {
        String hourBank[] = { "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
                "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen",
                "Nineteen", "Twenty", "Twenty one", "Twenty two", "Twenty three", "Twenty four", "Twenty five",
                "Twenty six", "Twenty seven", "Twenty eight", "Twenty nine" };

        if (minutes == 0) {
            timeName = hourBank[hours] + " O'clock";
        }

        else if (minutes == 15) {
            timeName = "A quarter past " + hourBank[hours];
        }

        else if (minutes == 30) {
            timeName = "Half Past " + hourBank[hours];
        }

        else if (hours == 12 && minutes == 45) {
            timeName = "A quarter to " + hourBank[hours - 11];
        }

        else if (minutes == 45) {
            timeName = "A quarter to " + hourBank[hours + 1];
        }

        else if (minutes <= 29) {
            timeName = hourBank[minutes] + " minutes past " + hourBank[hours];
        }

        else if (hours == 12 && minutes >= 31 && minutes <= 59) {
            timeName = hourBank[60 - minutes] + " minutes to " + hourBank[hours - 11];
        }

        else if (minutes >= 31 && minutes <= 60) {
            timeName = hourBank[60 - minutes] + " minutes to " + hourBank[hours + 1];
        } else {
            timeName = "That's not the correct format!";
        }

    }else{
        System.out.println("minutes are between 0 and 60 and hours are between 0 and 12");
    }
    return timeName;
}
  • Thank you! I am getting the following error for catch: ParseException cannot be resolved to a type. Is that my fault? – Luke Byrne Nov 26 '18 at 15:46
  • at which line, it is getting? and what is your input? – Erandika Harshani Nov 26 '18 at 15:49
  • I figured it out - it was an error on my part. My only question is that the above still has some errors for user input. For example, if I put in 12:68, the output is just "The time is: ", even though I want an error message there as minutes are between 0 and 60 and hours are between 0 and 12. – Luke Byrne Nov 26 '18 at 15:51
  • @LukeByrne Then add more validations to filter that cases – Rafael Palomino Nov 26 '18 at 15:56
  • In that case, you have to implement else part for your 1st if/else block in `getTimeName` method as,` else{System.out.println("there as minutes are between 0 and 60 and hours are between 0 and 12"); }` and `The time is:` is in you `s.o.p`. Therefore you can change it. – Erandika Harshani Nov 26 '18 at 15:57
  • Thank you. When you say add more validations, can I use Catch to do that? Sorry, I'm new to Java (coming from Python) and still trying to figure a lot of it out. Can I add the parameters to the catch statement? As mentioned, I want to catch the numbers greater than 60 or less than 0 for minutes, and catch hours greater than 12 or less than 0 for hours. – Luke Byrne Nov 26 '18 at 15:58
  • @LukeByrne: Updated my answer. try it. – Erandika Harshani Nov 26 '18 at 16:02
  • Thank you Erandika! That just prints out "minutes are between 0 and 60 and hours are between 0 and 12", but it does not reset to ask the user to re-input the time. – Luke Byrne Nov 26 '18 at 16:06
  • yes that is it, thank you so much! It's a great help. Can I ask, what exactly did you change? Just so I can read through the code and figure it out in more detail. – Luke Byrne Nov 26 '18 at 16:29
  • If this works, can you please [accept the answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235). :) And Please go through the code, then you can identify what i did. – Erandika Harshani Nov 26 '18 at 16:35