Покрытие строки в LocalTime с/без nanoOfSeconds

Мне нужно преобразовать строку в LocalTime (java-8, а не joda), которая может иметь или не иметь nanoOfSeconds в строке. Формат строки имеет форму 07:06:05 или 07:06:05.123456. Строка может иметь или не иметь десятичного знака в секундах, и когда это так, может быть любое количество символов для представления части наносекунд.

Использование DateTimeForamtter, например

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

or

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

Я могу использовать оператор IF, чтобы различать два формата, например:

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

Это отлично работает, и я согласен с этим, но мне нужно также использовать различное количество позиций после запятой.

Примерный набор данных может быть:

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

Есть ли способ разрешить средство форматирования анализировать любое количество цифр после запятой без выдачи java.time.format.DateTimeParseException, когда количество десятичных знаков неизвестно?

Я надеюсь, что упустил что-то действительно простое.


person jbolt    schedule 11.06.2015    source источник
comment
чтобы ответить на первый вопрос, кажется, вы могли бы просто проверить длину строки if (stringValue.length() > 7) { //use second formatter } else if (stringValue.length() == 7) { //use first formatter } Я не уверен, что понял второй вопрос, не могли бы вы уточнить?   -  person Blake Yarbrough    schedule 11.06.2015
comment
Я тоже не понимаю второго - надеюсь, это не имеет значения, учитывая мой ответ на первый :)   -  person Jon Skeet    schedule 11.06.2015
comment
Кажется некрасивым проверять определенное количество мест и выбирать формат на основе этого. Кажется логичным иметь средство форматирования, которое было бы немного менее строгим по количеству символов (но опять же, мы имеем дело со строками)   -  person jbolt    schedule 11.06.2015
comment
Ну, а не я соглашусь на комбинацию операторов if и ручного усечения строки до фиксированного количества позиций `if(strValue.length()› 12) { strValue = strValue.substring(0,12);}. Это уродливо, и надеюсь, что у кого-то есть лучшее предложение.   -  person jbolt    schedule 11.06.2015


Ответы (2)


Для разбора этого формата не нужно делать ничего особенного. LocalTime.parse(String) уже обрабатывает необязательные наносекунды:

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"));

Все вышеперечисленное анализируется нормально, см. также Javadoc спецификация.

person JodaStephen    schedule 13.06.2015
comment
что если в строке нет :? - person Gaspar; 22.03.2019
comment
как насчет 9:00? - person Febrinanda Endriz Pratama; 10.09.2019

Для этого вы можете использовать «необязательные разделы» шаблона формата:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:mm:ss[.SSSSSS]");
person Jon Skeet    schedule 11.06.2015
comment
да, но позволит ли это мне иметь различное количество десятичных знаков? - person jbolt; 11.06.2015
comment
@jbolt: было бы полезно, если бы вы уточнили свой вопрос, чтобы объяснить, что вы имеете в виду. - person Jon Skeet; 11.06.2015
comment
вопрос 2: мне нужно проанализировать неизвестное количество знаков после запятой. Это может быть 0 или более знаков (десятичное может даже не быть включено), следовательно, два разных тактовых размера. - person jbolt; 11.06.2015
comment
@jbolt: Это все еще не совсем ясно. Приведение примеров того, о чем вы просите, было бы намного яснее. - person Jon Skeet; 11.06.2015
comment
@jbolt: Не так много - вы говорите, что если есть более 3 знаков после запятой, вы все равно хотите проанализировать только первые три? Опять же, примеры не помешали бы — образец входных данных и ожидаемый результат. - person Jon Skeet; 11.06.2015