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\$
2
  • \$\begingroup\$Since the DateTimeFormatter is thread safe, did you try to reuse it ?\$\endgroup\$
    – gervais.b
    CommentedFeb 26, 2019 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\$CommentedFeb 26, 2019 at 14:18

1 Answer 1

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\$
0

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.