Java: синтаксический анализ нескольких строковых форматов даты и времени в LocalDateTime / Date / Calender - PullRequest
1 голос
/ 23 января 2020

Я пытаюсь разобрать строковую дату Время в LocalDateTime или Date в Java. Я могу получить входные данные, такие как 12/21/2020 12:12:12 PM, 1/12/2020 2:6:8 PM, 10/2/2020 10:50:8 AM

Я пытался использовать различные типы шаблонов в DateTimeFormatter или DateTimeFormatBuilder, которые могут работать. Метод грубой силы Где я жестко кодирую различные комбинации паттернов . Вот код, скопированный по ссылке:

import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;

class Main {
    public static void main(String[] args) {
        // many combinations
        final String DATE_FORMATS = "[MM/dd/yyyy HH:mm:ss a][M/dd/yyyy H:mm:ss a]";
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DATE_FORMATS);

        System.out.println(dateFormatter.parse("12/21/2020 11:12:12 AM"));
        System.out.println(dateFormatter.parse("1/12/2020 2:54:55 AM"));
    }
}

Есть ли другое решение, поскольку я не могу контролировать вход? Один шаблон, который я могу использовать в Formatter Вместо нескольких комбинаций? Или лучше изменить ввод после получения перед разбором?

Ответы [ 2 ]

4 голосов
/ 23 января 2020

tl; dr

LocalDateTime.parse(dateTimeString, DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a");
достаточно для всех ваших примеров datetime.


В следующем примере можно проанализировать все ваши примеры datetime String s с использованием LocalDateTime.parse вместо DateTimeFormatter.parse, которые отличаются:

public static void main(String[] args) {
    String first = "12/21/2020 12:12:12 PM";
    String second = "1/12/2020 2:6:8 PM";
    String third = "10/2/2020 10:50:8 AM";

    DateTimeFormatter dtf = DateTimeFormatter
            .ofPattern("[MM/dd/yyyy HH:mm:ss a][M/dd/yyyy h:m:s a][MM/d/yyyy HH:mm:s a]");

    System.out.println(LocalDateTime.parse(first, dtf));
    System.out.println(LocalDateTime.parse(second, dtf));
    System.out.println(LocalDateTime.parse(third, dtf));
}

Посмотрите на второй / средний шаблон, он использует h (нижний регистр) для часов вместо H (верхний регистр), потому что AM / PM дня будет также получен из заглавной буквы H, что приведет к конфликту во второй выборке даты и времени "1/12/2020 2:6:8 PM", где 02:06:08 считается AM , но за ним следует PM в шаблоне.

Вывод моего решения таков:

2020-12-21T12:12:12
2020-01-12T14:06:08
2020-10-02T10:50:08

, который правильно анализирует время до PM (14 = 02 PM).

Примечание:
Не используйте это DateTimeFormatter для вывода LocalDateTime.format(DateTimeFormatter), потому что оно вернет все три определенных форматирования ...
Очень некрасиво: 10/02/2020 10:50:08 AM10/02/2020 10:50:8 AM10/2/2020 10:50:8 AM

3 голосов
/ 23 января 2020

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

Итак, решение, которое я придумал, заключается в том, чтобы набор форматов хранился в файле свойств, а когда необходимо проанализировать строку, форматы читаются из файла и пытаются проанализировать Строки создаются последовательно с каждым форматом до тех пор, пока он не будет успешно проанализирован или пока у нас не закончатся форматы. Преимущества этого решения заключаются в том, что если вы обнаружите действительную строку, которая не была успешно проанализирована, все, что вам нужно будет сделать, это добавить новый формат в файл свойств, и повторная компиляция и повторное развертывание не требуются. Также таким образом вы можете установить свои приоритеты: скажем, если формат даты в США предпочтительнее европейского, просто поместите форматы США в первую очередь и только после европейских. Также в java 8 строки формата допускают необязательные разделы формата, обозначаемые как «[]». Таким образом, несколько форматов могут быть объединены в один с дополнительными разделами. Например, вместо

MM/dd/yyyy
MM-dd-yyyy
MM.dd.yyyy

вы можете просто написать

MM['/']['-']['.']dd['/']['-']['.']yyyy


Вот ссылка на полную статью

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...