2015-03-27 2 views
1

I`m пытаются построить форматировщик в JodaTime разобрать Период из строк, подобные этим:DateTime период с опциональными месяцев

  • год 1час 90мин
  • 1Year -60days 800min
  • 1год + 1months -1days + 1час -30min

Я знаю, что я могу построить синтаксический анализатор с PeriodFormatterBuilder в jodatime, но с ним я не могу разобрать первые два примера

PeriodFormatter formatter = new PeriodFormatterBuilder() 
    .appendYears().appendSuffix("year", "years").appendSeparatorIfFieldsAfter(" ") 
    .appendMonths().appendSuffix("month", "months").appendSeparatorIfFieldsAfter(" ") 
    .appendDays().appendSuffix("day", "days").appendSeparatorIfFieldsAfter(" ") 
    .appendHours().appendSuffix("hour", "hours").appendSeparatorIfFieldsAfter(" ") 
    .appendMinutes().appendSuffix("min", "mins").appendSeparatorIfFieldsAfter(" ") 
    .appendSeconds().appendSuffix("sec", "secs") 
    .toFormatter(); 

Есть ли какой-либо способ, которым я могу рассказать, что поля тоза не являются обязательными?

+0

Почему у вас есть смешанные знаки на вашем входе? Мне просто интересно. В строгом смысле это не одна продолжительность (период), а последовательность длительностей. Например: 1 месяц - 30 дней в будущем или в прошлом ??? Очень странно. - О вашем самом вопросе: Joda-Time не имеет понятия дополнительных секций в периодах синтаксического анализа (только секунды с дополнительными миллисами, не более). Может быть, специализированный 'PeriodParser' помогает, но я бы рекомендовал сначала применить токенизатор (проще). –

+0

Помогло ли решение PeriodParser решить проблему? –

ответ

1

Если вы действительно хотите достичь этого, вы можете сделать это, написав собственный парсер. Для этого вам придется реализовать класс PeriodParser и реализовать метод parseInto().

@Override 
public int parseInto(ReadWritablePeriod period, String periodStr, 
        int position, Locale locale) { 
    String tokens[] = periodStr.split(" "); 
    period.addYears(0); 
    period.addMonths(0); 
    period.addDays(0); 
    period.addHours(0); 
    period.addMinutes(0); 
    period.addSeconds(0); 
    for (String token : tokens) { 
     int count = 0; 
     if (token.contains("year")) { 
      String years = token.substring(0, token.indexOf("year")); 
      period.addYears(years.length() > 0 ? Integer.valueOf(years) : 0); 
      continue; 
     } 
     if (token.contains("hour")) { 
      period.addHours(Integer.valueOf(token.substring(0, token.indexOf("hour")))); 
      continue; 
     } 
     if (token.contains("min")) { 
      period.addMinutes(Integer.valueOf(token.substring(0, token.indexOf("min")))); 
      continue; 
     } 
     if (token.contains("months")) { 
      period.addMonths(Integer.valueOf(token.substring(0, token.indexOf("months")))); 
      continue; 
     } 
     if (token.contains("day")) { 
      period.addDays(Integer.valueOf(token.substring(0, token.indexOf("days")))); 
      continue; 
     } 
    } 
    return periodStr.length(); 
} 

После этого используйте следующий код для создания форматирования и разбора периода.

PeriodFormatterBuilder builder = new PeriodFormatterBuilder(); 
PeriodFormatter formatter = builder.append(null, new MyParsePeriod()).toFormatter();