Отформатируйте и преобразуйте целое число в минуты и секунды - PullRequest
0 голосов
/ 18 марта 2020

В моем приложении Java есть текстовое поле, в которое пользователи вводят числа, и нам нужно правильно проанализировать это число, чтобы отформатировать его в минуты и секунды. Вот таблица возможных значений и то, что должно быть произведено:

2     -> 02:00 OR 00:02
21    -> 00:21
215   -> 02:15
2157  -> 21:57

2:7   -> 02:07 OR 03:10
2:1   -> 02:01
2:71  -> 03:11
2:07  -> 02:07
20:7  -> 20:07 OR 21:10
20:61 -> 21:01

Детали OR Я все еще думаю, что должно быть лучшим способом сделать.

I ' Я уверен, что эта проблема была решена прежде, я просто ищу уже существующую библиотеку, которая может справиться с этим.

Ответы [ 2 ]

3 голосов
/ 18 марта 2020

В зависимости от того, какую опцию вы используете, вы можете сделать это, используя стандартные функции java .time

LocalTime time = LocalTime.of(value / 100, value % 100);
String timeString = time.format(DateTimeFormatter.ofPattern("HH:mm"));

Пример

for (int value : values) {
    LocalTime time = LocalTime.of(value / 100, value % 100);
    String timeString = time.format(DateTimeFormatter.ofPattern("HH:mm"));
    System.out.println(timeString);
}

00: 02
00: 21
02: 15
21: 57

2 голосов
/ 18 марта 2020

Подумайте о запрете ввода более 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

...