joda - разбор часового пояса pubDate в элементе RSS

Я анализирую pubDate в RSS-элементе, используя Joda. Дата должна быть в формате RFC-822: http://feed2.w3.org/docs/error/InvalidRFC2822Date.html

Проблема в том, что когда есть такая дата, как:среда, 02 октября 2002 13:00:00 по Гринвичу, я должен использовать шаблон:

DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss ZZZ").withLocale(Locale.ENGLISH).withOffsetParsed();

Но это также может быть дата: ср, 02 октября 2002 15:00:00 +0200. В этом случае ZZZ не работает, я должен использовать один Z:

DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z").withLocale(Locale.ENGLISH).withOffsetParsed();

Как создать универсальное решение?

2 ответа

Решение

Я сделал тесты с JodaTime 2.7 и нашел 2 способа сделать это:

  1. использование DateTimeFormatterBuilderНеобязательные парсеры:

    // create parser for "GMT"
    DateTimeParser gmtParser = DateTimeFormat.forPattern("ZZZ").getParser();
    
    // create parser for "+0200"
    DateTimeParser offsetParser = DateTimeFormat.forPattern("Z").getParser();
    
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("EEE, dd MMM yyyy HH:mm:ss ") // common pattern
        .appendOptional(gmtParser)    // optional parser for GMT
        .appendOptional(offsetParser) // optional parser for +0200
        .toFormatter().withLocale(Locale.ENGLISH).withOffsetParsed();
    
  2. DateTimeFormatterBuilder может получить массив синтаксических анализаторов, которые можно использовать для анализа различных входных данных:

    // create array with all possible patterns
    DateTimeParser[] parsers = {
        DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z").getParser(),
        DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss ZZZ").getParser()
    };
    
    // create a formatter using the parsers array
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .append(null, parsers) // use parsers array
        .toFormatter().withLocale(Locale.ENGLISH).withOffsetParsed();
    

Используя любое из приведенных выше решений, formatter будет работать с обоими входами:

System.out.println(formatter.parseDateTime("Wed, 02 Oct 2002 13:00:00 GMT"));
System.out.println(formatter.parseDateTime("Wed, 02 Oct 2002 15:00:00 +0200"));

Выход будет:

2002-10-02T13:00:00.000Z
2002-10-02T15:00:00.000+02:00

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

Обходное решение:

    dateTimeFormat = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss ZZZ").withLocale(Locale.ENGLISH).withOffsetParsed();
    dateTimeFormatOneZ = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z").withLocale(Locale.ENGLISH).withOffsetParsed();

private DateTime convertToDate(String pubDate) {

    try {
        return dateTimeFormat.parseDateTime(pubDate);
    } catch (Exception e) {
        try {
            return dateTimeFormatOneZ.parseDateTime(pubDate);
        } catch (Exception e1) {
            return null;
        }
    }
}
Другие вопросы по тегам