Использование API даты и времени Joda для анализа нескольких форматов

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

В настоящее время у меня есть код вроде этого:

try {
    return DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss").parseDateTime(datePart);
} catch (IllegalArgumentException e) {
    return DateTimeFormat.forPattern("E, MMM dd, yyyy HH:mm").parseDateTime(datePart);
}

Это работает, но противоречит совету Джошуа Блоха из Effective Java 2nd Edition (Пункт 57: Используйте исключения только для исключительных условий). Это также затрудняет определение того, происходит ли исключение IllegalArgumentException из-за закрученной даты/времени в файле журнала.

Можете ли вы предложить более хороший подход, который не злоупотребляет исключениями?

Ответ 1

Вы можете создать несколько парсеров и добавить их в конструктор с помощью метода DateTimeFormatterBuilder.append:

DateTimeParser[] parsers = { 
        DateTimeFormat.forPattern( "yyyy-MM-dd HH" ).getParser(),
        DateTimeFormat.forPattern( "yyyy-MM-dd" ).getParser() };
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append( null, parsers ).toFormatter();

DateTime date1 = formatter.parseDateTime( "2010-01-01" );
DateTime date2 = formatter.parseDateTime( "2010-01-01 01" );

Ответ 2

Joda-Time поддерживает это, позволяя указать несколько парсеров - DateTimeFormatterBuilder # append

Просто создайте свои два форматирования с помощью построителя и вызовите toParser() для каждого. Затем используйте построитель, чтобы объединить их с помощью append.

Ответ 3

К сожалению, я не верю, что у Joda Time есть такие возможности. Было бы неплохо иметь метод tryParseDateTime, но его не существует.

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

Обратите внимание, что DateTimeFormatter в Joda Time обычно неизменяемы - вы не должны создавать новый каждый раз, когда хотите разобрать строку. Создайте их один раз и повторно используйте их.