Строка до даты; Формат ввода варьируется

Для проекта, над которым я сейчас работаю, мне нужно преобразовать String в Date. К сожалению, формат даты и времени неодинаков во всех строках, которые необходимо преобразовать. В текущих значениях мы часто видим что-то вроде 2011-06-25T22:44:12 или 2011-06-25 22:49:01 (обратите внимание на букву T?).

Я знаю, как преобразовать String в Date с помощью SimpleDateFormat, но, поскольку я не знаю, какой формат будет у ввода, это не не кажется правильным подходом. Мне интересно, есть ли способ добавить несколько «форматов» к объекту DateFormat или, возможно, есть класс DateFormat, который может автоматически определять формат?

Другой подход, о котором я думал, заключается в использовании некоторых операторов if/else и регулярных выражений для String, чтобы выяснить, какой формат используется, и использовать класс SimpleDateFormat, который соответствует это, но я уверен, что должен быть более простой способ. Какие-либо предложения?


person Arno Moonen    schedule 25.06.2011    source источник


Ответы (3)


Если у вас есть несколько вариантов, а не только один с «T», а другой с пробелом, я считаю, что if/then/else с несколькими регулярными выражениями и сопоставлением SimpleDateFormats - это путь.

person Olaf    schedule 25.06.2011
comment
Я думал об этом подходе, но кажется, что много работы, когда есть много вариантов (я действительно ненавижу писать регулярные выражения). Возможно, я мог бы перебрать List объектов SimpleDateFormat, попытаться проанализировать строку и, если это удастся, разорвать цикл. Но я надеюсь, что есть лучший подход. - person Arno Moonen; 26.06.2011

Буква T внутри означает, что это стандартный формат ISO для даты http://en.wikipedia.org/wiki/ISO_8601. Однако имейте в виду, что этот формат с буквой «T» является лишь одним из нескольких вариантов, которые вы можете увидеть, когда дата представлена ​​в формате ISO 8601 (в одном из вариантов отсутствует время, в другом указан следующий часовой пояс).

Если вы знаете, что ваша дата будет соответствовать стандарту ISO 8601 (это очень часто для четко определенного XML - когда вы используете поля даты XSD, соответствующие ISO 8601), тогда SimpleDateFormat Java недостаточно - это слишком просто... Вместо этого вы можете вернуться к библиотеке JodaTime — в Joda Time уже есть средство форматирования ISO 8601, готовое к использованию: http://joda-time.sourceforge.net/api-release/org/joda/time/format/ISODateTimeFormat.html

Отредактировано: я бы не стал реализовывать какое-либо сложное сопоставление регулярных выражений - это затрудняет обслуживание и понимание кода в долгосрочной перспективе (особенно если у вас может быть много источников во многих форматах)

Предложение состоит в том, чтобы выяснить, какой провайдер использует какой формат, и применить шаблон стратегии: formatter = DateFormatterStrategyChooser.getFormatter(String source). Разделяй и властвуй.

И в случае, если вы не уверены на 100%, какой источник дает какую дату - вы все равно можете использовать UmbrellaFormatter(Collection) и проходить каждый форматтер последовательно, пока один не добьется успеха. Это лучше для удобства обслуживания, чем полагаться на неясные и сложные правила. .

person Jarek Potiuk    schedule 25.06.2011
comment
Библиотека JodaTime кажется хорошей библиотекой, но, к сожалению, я не могу быть уверен, что ввод всегда будет соответствовать стандарту ISO8601. Файлы, которые я обрабатываю, доставляются разными сторонами, и, к сожалению, время от времени мы видим разные форматы. Вот почему я думаю, что подход, использующий список возможных форматов, будет самым простым. - person Arno Moonen; 26.06.2011
comment
Конечно. Тогда вам действительно нужно создать набор синтаксических анализаторов и анализировать их один за другим, пока один из них не добьется успеха (я бы построил UmbrellaParser, передав ему набор синтаксических анализаторов во время создания, а затем пошел один за другим, пока один не добьется успеха)... , Только надеюсь, что вы не получите ГГГГ-ММ-ДД и ГГГГ-ДД-ММ из двух разных мест. Иногда они неразличимы. Другим (лучшим) вариантом было бы узнать, какой провайдер использует какой формат и применить шаблон стратегии: formatter = DateFormatterStrategyChooser.getFormatter(String source) - person Jarek Potiuk; 26.06.2011
comment
Спасибо за информацию, думаю, я выберу подход UmbrellaParser. - person Arno Moonen; 26.06.2011

Проверьте наличие буквы «Т», если она присутствует, проанализируйте строку и замените пробелом. Теперь вы можете использовать Date Formatter для создания объекта Date.

person Iñigo Beitia    schedule 25.06.2011
comment
Приведенные форматы — это всего лишь два из нескольких возможных форматов, поэтому, боюсь, это не лучшее решение проблемы. - person Arno Moonen; 26.06.2011