Автоматический анализатор даты/времени без указания формата

Я ищу библиотеку Java, которая может анализировать строку в POJO без указания формата. Я изучил POjava. Есть ли другая библиотека, которая делает что-то подобное?

DateTime dateTime = DateTimeParser.parse("21/02/13");

//If unclear use the cultural information passed
DateTime dateTime = DateTimeParser.parse("01/02/13", new Locale("en-us"));

//Should also work with time zones
DateTime dateTime = DateTimeParser.parse("2011/12/13T14:15:16+01:00");

Я нашел следующие ссылки с той же проблемой Интеллектуальный анализатор даты/времени для Java , но не очень полезные ответы. Ни Joda, ни JChronic не делают того, что я хотел. Поправьте меня, если я ошибаюсь.

Обновлять:

Причина, по которой я говорю, что Joda не решает мою задачу, заключается в том, что Joda ожидает, что строка будет проанализирована в формате ISO8601 или в любом формате, который вы укажете, например «yyyyMMdd». Я не смогу жестко закодировать этот формат, так как мне нужно обрабатывать несколько форматов.

У меня есть решение для устранения двусмысленности в отношении американских или европейских форматов даты, то есть мм/дд/гг или дд/мм/гг. Предполагая, что у меня есть доступ к часовому поясу даты, могу ли я определить, является ли это американским или европейским форматом? Может ли кто-нибудь сказать мне, как это сделать? Гуглил, но ничего не нашел.


person saravanan07    schedule 21.02.2013    source источник
comment
Что вы ожидаете от первой версии с 06/05/2013? Что бы вы ни выбрали, вы ошибетесь на значительную часть планеты.   -  person Jon Skeet    schedule 21.02.2013
comment
Вы смотрели Джода Тайм?   -  person    schedule 21.02.2013
comment
Если в первой строке есть неоднозначность, используйте информацию о культуре по умолчанию, если она не указана во второй строке кода.   -  person saravanan07    schedule 21.02.2013
comment
stackoverflow.com/a/4216288/300257   -  person Gilbert Le Blanc    schedule 21.02.2013
comment
Ну ты не прав, но и не прав. Невозможно, если вы не ограничите ввод однозначными форматами или не угадаете. Первое сделает вас непопулярным, второе — некомпетентным. :)   -  person Tony Hopkinson    schedule 21.02.2013
comment
проверьте этот github.com/zoho/hawking   -  person Heisenberg    schedule 01.04.2021


Ответы (6)


Проблема в том, что есть некоторые форматы, которые нельзя угадать правильно.

Простой пример: 01/02/2013. Это 1 февраля или 2 января? Или еще хуже: 01/02/09?

Оба формата существуют. (Спасибо, Великобритания и США!)

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

Модуль Python dateutil.parser может служить примером парсера с максимальной эффективностью. Извините, что я не знаю эквивалента Java. Но вы можете посмотреть Joda Time.

http://labix.org/python-dateutil#head-b95ce2094d189a89f80f5ae52a05b4ab7b41af47

на самом деле он имеет параметры dayfirst и yearfirst.

Затем есть Perl-модуль:

https://metacpan.org/pod/Time%3a%3aParseDate

Возможно, вы сможете использовать список приоритетов из этого модуля. Не очень быстро вслепую попробовать несколько шаблонов (оптимизированный лексер будет намного быстрее), но этого может быть достаточно для вас, если только вы не угадываете формат миллионов записей.

person Has QUIT--Anony-Mousse    schedule 21.02.2013
comment
Если в первой строке есть двусмысленность (см. код в исходном вопросе), используйте информацию о культуре по умолчанию, если она не указана во второй строке кода. Могу ли я получить такой интеллект из любой библиотеки? - person saravanan07; 21.02.2013

Я нашел ответ на свою проблему. Я использовал эту конкретную библиотеку POjava. На этой странице объясняется, как можно отформатировать строку даты и времени без указания какого-либо формата. Однако, чтобы библиотека работала правильно, вы должны указать порядок дат, например, день, за которым следует месяц, или месяц, за которым следует день.

person saravanan07    schedule 28.02.2013

Для этого нет волшебного решения. Помните, что форматы даты/времени также могут зависеть от вашего языка.

На самом деле лучшее, что вы можете сделать, это определить список форматов и «пробовать» их один за другим, пока не найдете подходящий (или ни одного).

private static final FORMAT_1 = "MM/dd/yyyy'T'HH:mm:ss.SSS"
private static final FORMAT_2 = "MM/dd/yyyy'T'HH:mm:ss"
private static final FORMAT_3 = "MM/dd/yyyy"

Не забывайте думать о безопасности потоков при работе с объектами даты/времени в java. У меня есть класс, который занимается такими вещами под названием "ThreadSafeDateTimeFormatter".

Удачи!

person vikingsteve    schedule 21.02.2013

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

public static Date returnDateFromDateString(String propValue) throws Exception {

    SimpleDateFormat sdfFormat1 = new SimpleDateFormat(IDateFConstants.DATE_STRING_FORMAT_1);
    SimpleDateFormat sdfFormat2 = new SimpleDateFormat(IDateFConstants.DATE_STRING_FORMAT_2);
    SimpleDateFormat sdfISO8601 = new SimpleDateFormat(IDateFConstants.DATE_STRING_ISO_8601);

    try {
        return sdfFormat1.parse(propValue);
    } catch (ParseException e) { }

    try {
        return sdfFormat2.parse(propValue);
    } catch (ParseException e) { }

    try {
        return sdfISO8601.parse(propValue);
    } catch (ParseException e) { }

    throw new Exception(IDateFConstants.DATE_FORMAT_ERROR);
}

где IDateFConstants выглядит

public interface IDateFConstants {

public static final String DATE_STRING_ISO_8601 = "yyyy-MM-dd'T'HH:mm:ss";
public static final String DATE_STRING_FORMAT_1 = "dd.MM.yyyy";
public static final String DATE_STRING_FORMAT_2 = "dd.MM.yyyy HH:mm:ss";

public static final String DATE_FORMAT_ERROR = "Date string wasn't" + 
                                            + "formatted in known formats";

}
person Miki    schedule 04.10.2016

Вам нужно, по крайней мере, иметь упорядоченный список кандидатов на шаблоны. После этого Apache В DateUtils есть метод parseDate(String dateString, String[] patterns), который позволяет легко попробовать список шаблонов в строке даты и проанализировать его по первому совпадению:

public static Date parseDate(String str,
                         String[] parsePatterns)
                  throws ParseException
Parses a string representing a date by trying a variety of different parsers.

Синтаксический анализ будет пробовать каждый шаблон синтаксического анализа по очереди. Анализ считается успешным только в том случае, если он анализирует всю входную строку. Если шаблоны синтаксического анализа не совпадают, генерируется исключение ParseException.

Парсер будет снисходителен к анализируемой дате.

person Sanchay    schedule 18.06.2018

Этот синтаксический анализатор даты/времени поддерживает более 20 форматов даты, пользователь может установить формат даты в качестве конфигурации для ввода. Ознакомьтесь с полным документом, и он делает больше, чем другие библиотеки даты и времени.

Ссылка на Github: https://github.com/zoho/hawking. Разработано командой ZOHO ZIA.

Hawking Parser — это синтаксический анализатор НЛП на основе Java для анализа информации о дате и времени. Самые популярные парсеры, такие как Heidel Time, SuTime и парсер времени Natty Date, явно основаны на правилах. Таким образом, они часто имеют тенденцию бороться с синтаксическим анализом информации о дате/времени, когда необходимо учитывать более сложные факторы, такие как контекст, время, несколько значений и многое другое.

Имея это в виду, Hawking Parser предназначен для решения многих из этих проблем и имеет много явных преимуществ по сравнению с другими доступными парсерами даты/времени.

Это библиотека с открытым исходным кодом под GPL v3 и лучшая из них. Чтобы узнать, почему это лучше всего, ознакомьтесь с этим блогом, в котором подробно объясняется: now-open-source.html" rel="nofollow noreferrer">https://www.zoho.com/blog/general/zias-nlp-based-hawking-date-time-parser-is-now-open-source .html

P.S: я один из разработчиков этого проекта

person Heisenberg    schedule 01.04.2021
comment
Я заметил, что вы написали несколько ответов, ссылающихся на ваш сайт. Пока все они кажутся относящимися к вопросам, а ответов всего несколько, так что все в порядке. Но я должен предупредить вас, что даже если вы раскроете свою принадлежность к связанным ресурсам, продолжение повторного и/или без необходимости продвижения вашего контента может быть расценено как спам. Дополнительную информацию об этом см. в разделе Как не стать спамером. - person cigien; 02.04.2021
comment
Спасибо, что дал мне знать. буду иметь это в виду, прежде чем публиковать ответы - person Heisenberg; 02.04.2021