Java. В строке несколько записей времени, время дано в 24-час формате с лидирующим нулем. Найти такие подстроки и заменить время на 12-час формат

Пример: на вход идет строка String string = "Breakfast 07:25, Lunch 13:00, Dinner 20:10, 24:10, 123:2a 31:20 10:60 10:80 1:20";

На выходе должно получиться String expected = "Breakfast 7:25 AM, Lunch 1:00 PM, Dinner 8:10 PM, 24:10, 123:2a 31:20 10:60 10:80 1:20";

Нужно реализовать это с помощью работы со строками и взаимодействием с LocalDate/Time API и Date Formatter'ами. Можно использовать regexы Я пытался реализовать примерно таким образом, но обработка происходит только для первого элемента.

public static String changeTimesTo12h(String string) {
        String[] elements = string.split(",");
        Pattern pattern = Pattern.compile("([A-Z]{1}[a-z]+){1}\\s([0-9]{2}:\\d\\d)");
        SimpleDateFormat format = new SimpleDateFormat("hh:mm a");
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < elements.length; i++) {
            Matcher matcher = pattern.matcher(elements[i]);
            if (matcher.matches()) {
                result.append(matcher.group(1) + " ");
                result.append(matcher.replaceFirst(LocalTime.parse(matcher.group(2)).format(DateTimeFormatter.ofPattern("h:mm a"))));
                result.append(",");
            } else {
                result.append(elements[i] + ",");
            }
        }
        return String.valueOf(result);

Помогите, пожалуйста, хочу разобраться как сделать.


Ответы (1 шт):

Автор решения: Nowhere Man

Во-первых, определяем корректное регулярное выражение для поиска времени в формате "HH:mm", где часы принимают значение в диапазоне [00..23], а минуты соответственно [00..59]. Затем каждую отметку времени, найденную в исходной строке при помощи Matcher, можно преобразовать в другой формат при помощи метода Matcher::replaceAll(Function<MatchResult,String> replacer), добавленного в Java 9.

Соответственно, во-вторых понадобится определить функцию для преобразования формата, принимающую MatchResult, и возвращающую строку. В такой функции как раз имеет смысл использовать два формата: входной HH:mm и выходной h:mm a.

public static String fixTime(String str) {
    Pattern time = Pattern.compile("([01]\\d|2[0-3]):([0-5]\\d)");
    
    return time.matcher(str).replaceAll(MyClass::convertTime);
}

private static final DateTimeFormatter HH_MM = DateTimeFormatter.ofPattern("HH:mm"); // 00..23
private static final DateTimeFormatter H_MM_A = DateTimeFormatter.ofPattern("h:mm a"); // 1..12

private static String convertTime(MatchResult hhMM) {
    return LocalTime.parse(hhMM.group(), HH_MM).format(H_MM_A);
}

Тест:

System.out.println(fixTime("Breakfast 07:25, Lunch 13:00, Dinner 20:10, 24:10, 123:2a 31:20 10:60 10:80 1:20 Midnight 00:00, noon lunch 12:00"));
// -> Breakfast 7:25 AM, Lunch 1:00 PM, Dinner 8:10 PM, 24:10, 123:2a 31:20 10:60 10:80 1:20 Midnight 12:00 AM, noon lunch 12:00 PM
→ Ссылка