Search code examples
javajodatimedatetime-formatandroid-jodatime

How to parse time (hour, minute) from a string?


Anybody know how to parse time (hour, minute and AM/PM) from a string that looks like "01:20" -> 1:20AM and "21:20" -> 9:20PM? Most solutions out there seem to assume or require a Date or Calendar object.

My input time is actually coming from a TimePickerDialog (specifically, this MaterialDateTimePicker implementation, so I receive only the hourOfDay, minute and seconds (integers).

I want to be able to format the time that the user picked in a friendly way, i.e 12:30PM, 02:15AM, etc.

I am trying to use Joda Time:

fun formattedTime(timeStr: String): String {
    // Get time from date
    val timeFormatter = DateTimeFormat.forPattern("h:mm a")
    val displayTime = timeFormatter.parseLocalTime(timeStr)
    return displayTime.toString()
}

but I get this error with an input string such as "1:20": java.lang.IllegalArgumentException: Invalid format: "1:20" is too short

I have also looked into SimpleDateFormat but it seems to require a full date-time string such as in this related question


Solution

  • As @ole-v-v pointed out, SimpleDateFormat has seen better days - so today you can make use of the java.time package to do the job:

    java.time.format.DateTimeFormatter target2 = 
         java.time.format.DateTimeFormatter.ofPattern("h:mm a");
    java.time.format.DateTimeFormatter source2 = 
         java.time.format.DateTimeFormatter.ofPattern("HH:mm");
    
    System.out.println("01:30 -> " + target2.format(source2.parse("01:30")));
    System.out.println("21:20 -> " + target2.format(source2.parse("21:20")));
    

    Yields the result of

    01:30 -> 1:30 AM
    21:20 -> 9:20 PM
    

    as expected.

    In Joda-Time you would code it as @meno-hochschild pointed out in his answer below.

    Using SimpleDateFormat it will look like this:

        SimpleDateFormat target = new SimpleDateFormat("h:mm a");
        SimpleDateFormat source = new SimpleDateFormat("HH:mm");
        System.out.println("01:30 -> " + target.format(source.parse("01:30")));
        System.out.println("21:20 -> " + target.format(source.parse("21:20")));
    

    This will parse from 24h times to 12 hours display

        01:30 -> 1:30 AM
        21:20 -> 9:20 PM      
    

    It all depends on the format for the hours - for parsing you'll want 24h hours (format HH), for output you want 12 hours plus am / pm - format is h.

    If you want 01:30 to be PM you'll have to add that to the string to be parsed somehow:

       System.out.println("01:30 pm-> " + target.format(target.parse("01:30 pm")));
    

    resulting in

       01:30 pm-> 1:30 PM