1
\$\begingroup\$

I have a method that can take in a time string in one of the following formats:

  1. HHmmss - e.g. 073055 = 07:30:55

  2. HHmm - e.g. 0730 = 07:30:00

  3. HHmm'H - e.g. 0730H = 07:30:30

  4. a whitespace or empty string - return null

My current code is as follows:

private final static String timeFormatPattern = "HHmmss";
private final static DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(timeFormatPattern);

private static LocalTime getLocalTime(String inputTime)
{
    if (inputTime.trim().equals(""))
    {
        return null;
    }
    else
    {
        char secondsIndicator = inputTime.charAt(4);

        if (secondsIndicator == ('H'))
        {
            // H = 30 seconds
            return LocalTime.parse(inputTime.substring(0, 4) + "30", timeFormatter);
        }
        else if (secondsIndicator == (' '))
        {
            // no H = 00 seconds
            return LocalTime.parse(inputTime.substring(0, 4) + "00", timeFormatter);
        }
        else // specific time provided
        {
            return LocalTime.parse(inputTime,timeFormatter);
        }
    }
}

Profiling shows that this method takes 16,439 milliseconds over 7.6 million invocations; and thus is the method with the highest self time in my program's startup.

I have tried splitting this into two methods (one to format the string, and one that simply contains return LocalTime.parse(formattedTime, timeFormatter);), to see whether it was the LocalTime.parse or my string manipulation that was slow. It turns out that 2/3 of the processing is from LocalTime.parse, and the other 1/3 from the string manipulation. This is with half the inputs being of the 4th type (and so not calling the LocalTime.parse at all); and half being of the 2nd or 3rd type.

Am I missing a more efficient way of getting the LocalTime here?

\$\endgroup\$
  • \$\begingroup\$ Since the DateTimeFormatter is thread safe, did you try to reuse it ? \$\endgroup\$ – gervais.b Feb 26 at 12:44
  • \$\begingroup\$ I didn't; but I have now and it hasn't changed the numbers (still approx. 12,000 ms for the LocalTime.parse) - I'll update the question \$\endgroup\$ – simonalexander2005 Feb 26 at 14:18
1
\$\begingroup\$

Since your format is relatively constant I would suggest parsing it yourself into hours and minutes and seconds and use the LocalTime.of method. It could look something like this:

public static LocalTime getLocalTime(String inputTime){
    if (inputTime.trim().equals(""))
    {
        return null;
    }
    int hour = ((inputTime.charAt(0)-'0')*10)+(inputTime.charAt(1) - '0');
    int minutes = ((inputTime.charAt(2)-'0')*10)+(inputTime.charAt(3)-'0');
    int seconds = 0;
    if(inputTime.length() != 4){
        if(inputTime.charAt(4) == 'H'){
            seconds = 30;
        }else{
            seconds = ((inputTime.charAt(4)-'0')*10)+(inputTime.charAt(5)-'0');
        } 
    }
    return LocalTime.of(hour, minutes, seconds);
}
\$\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.