18

I need to convert a string to LocalTime (java-8 not joda) that may or maynot have nanoOfSeconds in the string. The String format is in the form of 07:06:05 or 07:06:05.123456 The string may or may not have a decimal place in the seconds and when it does there could be any number of characters to represent the Nano Seconds part.

Using a DateTimeForamtter such as

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:mm:ss");

or

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:mm:ss.SSSSSS");

I can use an IF statement to distinguish between the two formats such as:

DateTimeFormatter dtf;
if (time1.contains(".") {
   dtf = DateTimeFormatter.ofPattern("H:mm:ss.SSSSSS);
} else {
   dtf = DateTimeFormatter.ofPattern("H:mm:ss);
}

This works fine and I'm OK with this but I need to be able to also use a varying number of positions after the decimal point.

A sample data set might be:

[11:07:59.68750, 11:08:00.781250, 11:08:00.773437500, 11:08:01]

Is there a way to allow the formatter to parse any number of digits after the decimal without it throwing a java.time.format.DateTimeParseException when the number of decimal places is unknown?

I'm hoping I missing something really simple.

assylias
  • 321,522
  • 82
  • 660
  • 783
jbolt
  • 688
  • 3
  • 16
  • 37
  • to answer the first question, it seems that you could simply test the length of the string `if (stringValue.length() > 7) { //use second formatter } else if (stringValue.length() == 7) { //use first formatter }` I'm not sure I understand the second question, could you elaborate? – Blake Yarbrough Jun 11 '15 at 18:16
  • 1
    I don't understand the second either - I'm hoping it's irrelevant given my answer to the first :) – Jon Skeet Jun 11 '15 at 18:18
  • Seems ugly to have to check for a specific number of places and decide on a format based on that. Seems logical to have a formatter that was a little less strict on number of characters (but then again we are dealing with strings) – jbolt Jun 11 '15 at 18:26
  • Well for not I will settle for a combination of if statements and manually truncating the string to a fixed number of positions `if(strValue.length()> 12) { strValue = strValue.substring(0,12);}. This is ugly and hope someone has a better suggestion. – jbolt Jun 11 '15 at 19:20

2 Answers2

45

There is no need to do anything special to parse this format. LocalTime.parse(String) already handles optional nanoseconds:

System.out.println(LocalTime.parse("10:15:30"));
System.out.println(LocalTime.parse("10:15:30."));
System.out.println(LocalTime.parse("10:15:30.1"));
System.out.println(LocalTime.parse("10:15:30.12"));
System.out.println(LocalTime.parse("10:15:30.123456789"));

All the above parse fine, see also the Javadoc spec.

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
8

You could use "optional sections" of the format pattern for this:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:mm:ss[.SSSSSS]");
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • yea but will that let me me have a varied amount of decimal places? – jbolt Jun 11 '15 at 18:18
  • 2
    @jbolt: It would help if you would clarify your question to explain what you mean. – Jon Skeet Jun 11 '15 at 18:18
  • question 2 was I need to parse an unknown number of places after the decimal. It could be 0 or more places (the decimal could even not be included) hence the two different time signatures – jbolt Jun 11 '15 at 18:21
  • 2
    @jbolt: That's still not really clear. Giving examples of what you're asking for would be a lot clearer. – Jon Skeet Jun 11 '15 at 18:30
  • 2
    @jbolt: Not a lot - are you saying if there *are* more than 3 decimal places, you still only want to parse the first three? Again, *examples* would help - sample input and expected output. – Jon Skeet Jun 11 '15 at 18:45