2015-05-08 4 views
0

Этот код:java.lang.IllegalArgumentException: Неверный формат

DateTimeParser[] parsers = { DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss zzz").getParser(), 
DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss").getParser(), DateTimeFormat.forPattern("dd/MM/yyyy HH:mm").getParser(), 
DateTimeFormat.forPattern("HH:mm").getParser() }; 
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, parsers).toFormatter(); 

Session session; 
DateTime dTime = null; 
Calendar calendar; 

try{ 
    if (completedTime != null && !completedTime.equalsIgnoreCase("")){ 
     LocalDateTime jt = LocalDateTime.parse(completedTime, formatter); 
     LocalDateTime dt; 
     LocalDateTime retDate; 

производит ошибку:

java.lang.IllegalArgumentException: Invalid format: "09/05/2015 04:00:00 GDT" is malformed at " GDT" at the LocalDateTime jt = LocalDateTime.parse(completedTime, formatter); line

Я не могу за жизнь мне понять, почему это не удается. Я почти уверен, что это что-то простое, но я этого не заметил.

+1

Вы уверены, что 'GDT' является идентификатором часового пояса, который поддерживается? – Jesper

+0

не должно быть 'z'? ; Я думаю, что существует только 'z' для короткой версии и' zzzz' для полной текстовой версии. – bvdb

+0

Насколько я могу судить, GDT является синонимом BST (British Summer Time) на платформе базы данных, которую я использую.Поскольку это не несущественно для системы, над которой я работаю, я просто снимаю ее, чтобы справиться с этой проблемой. –

ответ

0

Вам необходимо вручную указать отображение с сокращением часовой пояс в часовой пояс. Например:

return new DateTimeFormatterBuilder() 
       .appendPattern("dd/MM/yyyy HH:mm:ss ") 
       .appendTimeZoneShortName(UK_TIMEZONE_SYMBOLS) 
       .toFormatter(); 

Здесь UK_TIMEZONE_SYMBOLS является Map<String,DateTimeZone>, который содержит наш взгляд имен часовых поясов (так BST британка летнее время, не Бангладеш стандартное время)

Вот как мы строим наши:

public static Map<String, String> buildTimeZoneSymbolMap(Locale locale) { 
    Map<String, String> timeZoneSymbols = Maps.newLinkedHashMap(); 
    for (String[] zoneInfo : DateFormatSymbols.getInstance(locale).getZoneStrings()) { 
     String timeZone = zoneInfo[0]; 
     if (!timeZoneSymbols.containsKey(zoneInfo[2])) { 
      timeZoneSymbols.put(zoneInfo[2], timeZone); 
     } 
     if (zoneInfo[4] != null && !timeZoneSymbols.containsKey(zoneInfo[4])) { 
      timeZoneSymbols.put(zoneInfo[4], timeZone); 
     } 
    } 
    timeZoneSymbols.put("UTC", "GMT"); 
    return timeZoneSymbols; 
} 

public static Map<String, DateTimeZone> buildDateTimeZoneSymbolMap(Locale locale) { 
    return Maps.transformValues(buildTimeZoneSymbolMap(locale), input -> DateTimeZone.forTimeZone(TimeZone.getTimeZone(input))); 
} 

public static final Map<String, DateTimeZone> UK_TIMEZONE_SYMBOLS = ImmutableMap.copyOf(buildDateTimeZoneSymbolMap(Locale.UK)); 
+0

Что будет выглядеть UK_TIMEZONE_SYMBOLS? – doughgle

+0

@ Отмените только карту из строки часового пояса, чтобы распознать экземпляр DateTimeZone для использования, например. 'ImmutableMap.of (" GMT ", DateTimeZone.UTC)'. Фактически мы собираем наши данные из локальных данных: я добавлю код в ответ. – araqnid

1

Возможно, вы захотите обратиться к this ниткам (или одному из многих других). Мой лучший совет - попытаться разрезать только на один «z» в вашем парсере.

0

Первое, что нужно отметить:

Что такое "GDT"? Веб-сайт http://www.timeanddate.com/time/zones/ не дает ответа. Так что, если он действительно существует и не является опечаткой, то какова ваша локаль? Помните, что названия и аббревиатуры часовых поясов сильно локализованы.

Второе: Количество символов шаблона «г» в порядке - для классов, как SimpleDateFormat и т.д. - см его documentation. Либо четыре буквы для полного имени или менее четырех букв аббревиатуры:

General time zone: Time zones are interpreted as text if they have names. Text: For formatting, if the number of pattern letters is 4 or more, the full form is used; otherwise a short or abbreviated form is used if available. For parsing, both forms are accepted, independent of the number of pattern letters.

Но вы используете Joda-Time. Его документация четко говорится:

Zone names: Time zone names ('z') cannot be parsed.

Я проверил это не-поддержки с использованием новейших Joda-Time версии 2.7 с помощью следующего кода:

DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss z").withLocale(Locale.GERMANY); 
    DateTime dt = formatter.parseDateTime("09/05/2015 04:00:00 MESZ"); 
    System.out.println("Joda-Time: " + dt); 
    // Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "09/05/2015 04:00:00 MESZ" is malformed at "MESZ" 

Конечно, «MESZ» правильно и должно быть истолковано как Europe/Berlin в контексте данного немецкого языка.

Однако, поскольку обновление версии (2.2) того же кода, установленного на Locale.US, работает в течение нескольких часовых поясов, таких как «EDT», «PST» и т. Д., См. Также этот commit. Поэтому мы можем, наконец, сказать, что синтаксическая поддержка Joda-Time для названий и сокращений часового пояса лучше всего сказать очень ограниченно. Еще раз, какой у вас Locale? Если это не США, то я могу понять, почему вы получаете исключение. И вы также получите исключение для ввода «GDT», даже если считать его действительным из-за ограниченных возможностей Joda-Time-parser.

Смежные вопросы