Подумайте о запрете ввода более 59 секунд. Я сомневаюсь, что у пользователей была бы какая-то причина хотеть сделать это, поэтому 2:71 - это скорее опечатка, и вы можете оказать пользователю услугу, когда узнаете об этом. По крайней мере, разрешайте это, только когда нет минут.
RegEx и Duration
В любом случае, для вопроса, который задают, одним из предложений является использование регулярного выражения и класса Duration
например:
Pattern durationPattern = Pattern.compile("(?:(\\d{1,2}?):?)??(\\d{1,2})");
String[] inputs = { "2", "21", "215", "2157", "2:7",
"2:1", "2:71", "2:07", "20:7", "20:61" };
for (String input : inputs) {
Matcher m = durationPattern.matcher(input);
if (m.matches()) {
String minuteStringOrNull = m.group(1);
String secondString = m.group(2);
Duration dur = minuteStringOrNull == null ? Duration.ZERO : Duration.ofMinutes(Integer.parseInt(minuteStringOrNull));
dur = dur.plusSeconds(Integer.parseInt(secondString));
String durationString = String.format("%02d:%02d", dur.toMinutes(), dur.toSecondsPart());
System.out.format("%-5s -> %s%n", input, durationString);
} else {
System.out.println("Invalid input: " + input);
}
}
Вывод этого фрагмента кода:
2 -> 00:02
21 -> 00:21
215 -> 02:15
2157 -> 21:57
2:7 -> 02:07
2:1 -> 02:01
2:71 -> 03:11
2:07 -> 02:07
20:7 -> 20:07
20:61 -> 21:01
Что мне не нравится в этом, так это то, что регулярное выражение так трудно читать (?:(\\d{1,2}?):?)
- это группа без захвата, (?:
… )
работает так же, как скобки в математике и программировании. И ??
после того, как он говорит, что он может быть или не быть там, и неохотно принимайте его, то есть, попробуйте сначала без него, затем с. Таким образом, когда цифр мало, мы используем их не на минуты, а на секунды. Внутри группы (\\d{1,2}?)
находится группа захвата, состоящая из 1 или 2 цифр (в течение нескольких минут), опять же неохотно, предпочтение от 1 до 2. :?
означает, что за 1 или двумя цифрами может следовать или не следовать двоеточие. Наконец, (\\d{1,2})
- это другая группа захвата из 1 или 2 цифр (для секунд). Группы захвата - это то, что мы убираем, используя m.group()
позже в коде (они нумеруются с 1).
Если вы в конечном итоге выбираете другие интерпретации, вы, вероятно, можете изменить идею и / или код соответственно.
Более читабельная альтернатива
Вы можете предпочесть более легко читаемый код, даже если он длиннее. В этом случае ручной анализ может быть лучше, чем использование регулярного выражения. Я полагаю, что вы можете построить алгоритм по следующим неполным строкам (не проверено).
String[] parts = input.split(":", 3);
if (parts.length == 1) { // no colon
if (input.length > 2) {
// take last two digits as seconds, everything else as minutes
} else {
// take everything as seconds
}
} else if (parts.length == 2) {
// take minutes from parts[0] and seconds from parts[1]
} else {
// invalid input, too many colons
}
Все еще использовать класс Duration
, как и раньше.
Существующая библиотека?
Это вне топики c для переполнения стека, но теперь мы находимся на этом: я не знаю достаточно хорошо, чтобы сказать, но вы можете увидеть, Time4J или Joda- Здесь может помочь время .
Ссылка
Документирование регулярных выражений в Java