Требуется гибкое преобразование даты и времени с помощью joda

Я хочу использовать joda для разбора строк datetime в электронных письмах. К сожалению, я получаю все виды разных форматов, например

Wed, 19 Jan 2011 12:52:31 -0600
Wed, 19 Jan 2011 10:15:34 -0800 (PST)
Wed, 19 Jan 2011 20:03:48 +0000 (UTC)
Wed, 19 Jan 2011 17:02:08 -0600 (CST)
Fri, 21 Jan 2011 10:39:55 +0100 (CET)
Fri, 21 Jan 2011 17:50:42 -0500 (EST)
Wed, 06 Apr 2011 15:38:25 GMT
Thu, 7 Apr 2011 11:38:24 +0200 
Fri,  8 Apr 2011 05:13:36 -0700 (MST)
20 Apr 2011 03:00:46 -0400

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

Есть ли более элегантный способ справиться с этим? Просьба сообщить.

            DateTimeParser[] parsers = {
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(CET)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(CST)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(CEST)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(GMT)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(MST)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(PST)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(UTC)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(EST)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(EDT)'").getParser(),
                    DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '(CDT)'").getParser(),
            };
            DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder().append(null, parsers).toFormatter();

            try {
                calendar = inputFormatter.withLocale(Locale.US).parseDateTime(date[0]);
            }
            catch(Exception e) {
                System.out.println("problem with " + date[0]);
            }

Ответ 1

Вне использования Joda DateTimeParser самостоятельно и, по существу, разбирая текст, вы создаете действительный DateTime (который, я думаю, будет большой работой), я не думаю, что в вашем подходе действительно очень плохо. Я думаю, что у вас слишком много форматов. Я думаю, что ваш набор форматов может быть уменьшен до:

 DateTimeParser[] parsers = {
     DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z").getParser(),
     DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z '('z')'").getParser(),
     DateTimeFormat.forPattern("E, d MMM y HH:mm:ss z").getParser(),
     DateTimeFormat.forPattern("dd MMM y HH:mm:ss Z").getParser(),
 };

Z (Capital-Z) - это цифровой часовой пояс RFC 822, а small-z - акроним для часового пояса, например PDT. Это по-прежнему (в среднем) 2 исключения, отправленные на один запрос, но если это не должно быть высокопроизводительным, это, вероятно, не так уж плохо.

Ответ 2

Единственный "более элегантный" способ справиться с этим - написать собственную реализацию DateTimeParser. Используя DateTimeFormatterBuilder, вы можете склеивать детали, которые работают (день/месяц/разбор зон), с частями, которые не работают (синтаксический анализ одного или нескольких пробелов, синтаксический анализ аббревиатуры произвольного часового пояса в скобках), написание нового парсера только для этих битов которые нуждаются в специальном форматировании.