Java обрабатывает несколько возможно неизвестных форматов даты / времени
Я пытаюсь создать что-то, что может проверять дату / время многих форматов, чтобы увидеть, является ли это действительной датой / временем, чтобы я мог обработать это. Его обработка состоит в преобразовании даты / времени во что-то, нормализованное для моего программного обеспечения для работы. Проблема в том, что мне нужно было бы выполнить проверку различными способами, чтобы попытаться определить дату с помощью SimpleDateFormat, но действительно было трудно получить все варианты. Проект связан с анализом CSV-файлов с потенциально указанными пользователем форматами даты в столбце даты. Есть ли способ лучше? Вот что я делаю сейчас:
public static boolean isDateValid(String dateString)
{
ArrayList<SimpleDateFormat> dateFormats = new ArrayList<SimpleDateFormat>();
dateFormats.add(new SimpleDateFormat("M/dd/yyyy"));
dateFormats.add(new SimpleDateFormat("dd.M.yyyy"));
dateFormats.add(new SimpleDateFormat("M/dd/yyyy hh:mm:ss"));
dateFormats.add(new SimpleDateFormat("dd.M.yyyy hh:mm:ss"));
dateFormats.add(new SimpleDateFormat("dd-M-yyyy hh:mm:ss"));
dateFormats.add(new SimpleDateFormat("M-dd-yyyy hh:mm:ss"));
dateFormats.add(new SimpleDateFormat("yyyy-M-dd hh:mm:ss"));
dateFormats.add(new SimpleDateFormat("dd.MMM.yyyy"));
dateFormats.add(new SimpleDateFormat("dd-MMM-yyyy"));
dateFormats.add(new SimpleDateFormat("M/dd"));
dateFormats.add(new SimpleDateFormat("M dd"));
dateFormats.add(new SimpleDateFormat("M y"));
for (SimpleDateFormat format : dateFormats)
{
try
{
format.setLenient(false);
Date date = format.parse(dateString);
return true;
}
catch (Exception e)
{
}
}
return false;
}
Кроме того, я также попытался использовать DateUtils из Apache Commons, но, похоже, мне все равно придется циклически проходить через кучу дат.
public static boolean isDate(String dateString)
{
try
{
Date theDate = DateUtils.parseDate(dateString);
}
catch (Exception e)
{
System.out.println(e);
return false;
}
return true;
}
Любые идеи или слова ободрения?
3 ответа
Одна из проблем вашего текущего подхода заключается в том, что вы создаете все эти экземпляры SimpleDateFormat без необходимости, когда знаете, что собираетесь использовать только один из них. Вместо этого используйте регулярные выражения, чтобы определить, какую строку даты вы получаете, а затем выполните одно из двух действий: 1) создать экземпляр только нужного вам средства форматирования или 2) манипулировать строкой в стандартном формате, который можно проанализировать с помощью одного из них. общий форматер.
Ну, вот мое предложение:
Вам следует сузить типы поддерживаемых форматов даты. Это удобно для поддержки любого типа формата даты, например,一九九零年三月一日 является допустимым форматом даты на китайском языке.
И у нас есть метод двойной проверки для определения правильной даты следующим образом:
public boolean isDate(String dateStr, DateFormat format){ boolean result = false; try { Date date = format.parse(dateStr); if (format.format(date).equals(dateStr)) { result = true; } } catch (Exception e) { result = false; } return result; }
Поскольку SimpleDateFormat "2013/4/31" переводится как "2013/5/1", последнее апреля - 30-го, верно?
Мне поручили подобную проблему на работе, где я был вовлечен в процесс ETL для загрузки данных из исходного файла в хранилище. Форматы даты варьируются от одного источника к другому. Мое решение идет с приведенным примером цикличности. Есть возможность использовать parsePosition вместо зацикливания. Однако есть несколько способов улучшить код зацикливания, чтобы не создавать экземпляр SimpleDateFormat снова (уже опубликовано). Вместо этого просто используйте applyPattern
, Кроме того, хранение различных форматов в виде простого файла (конфигурации) позволит лучше настраивать и адаптироваться к новым форматам. Я разместил свою реализацию по следующей ссылке. Это может помочь.