Время Джоды - Разбор строки вызывает java.lang.IllegalArgumentException

Не следует ли синтаксический анализ String, отформатированный с определенным DateTimeFormatter, с помощью LocalDateTime.parse()?

Test

DateTimeFormatter formatter = ISODateTimeFormat.dateTimeNoMillis()
LocalDateTime ldt = new LocalDateTime()
String val = ldt.toString(formatter)
System.out.println(val) //2013-03-26T13:10:46
// parse() throws java.lang.IllegalArgumentException: Invalid format: "2013-03-26T13:10:46" is too short
LocalDateTime nldt = LocalDateTime.parse(val, formatter) 

Ответ 1

Посмотрите JavaDoc:

Возвращает базовый форматтер, который объединяет базовую дату и время без миллинов, разделенных "T" (yyyyMMdd'T'HHmmssZ). Смещение часового пояса - "Z" для нуля и формы "± HHmm" для ненулевого. По умолчанию синтаксический анализатор строгий, поэтому строка 24:00 не может быть проанализирована.

Ключ здесь, по-видимому, является смещением часового пояса, равным "Z" для нуля, и формы "± HHmm" для ненулевого. Время Joda, очевидно, ожидает информацию о часовом поясе для parse().

Я добавил "Z" к вашей разобранной дате String и работает лучше:

DateTimeFormatter formatter = ISODateTimeFormat.dateTimeNoMillis();
LocalDateTime ldt = new LocalDateTime();
String val = ldt.toString(formatter);
System.out.println(val);    
val += "Z";
LocalDateTime nldt = LocalDateTime.parse(val, formatter);
System.out.println(nldt.toString());

Выход:

2013-03-26T17:50:06
2013-03-26T17:50:06.000

Ответ 2

Форматировщик также выдает ошибку, если вызывается formatter.parseLocalDateTime(val), что то, что LocalDateTime.parse(...) вызывает напрямую (т.е. наивный вызов).

Итак, это фактор ожидаемого формата, который в этом случае равен yyyy-MM-dd'T'HH:mm:ssZZ; в основном, он жалуется, что вы не прошли часовой пояс.

Я не знаю, действительно ли это означает "ошибка"; в краткосрочной перспективе, очевидно, может использоваться пользовательский формат или посмотреть ISODateTimeFormat.localDateOptionalTimeParser(), который, по-видимому, вам нужен (он парсер по умолчанию, используемый LocalDateTime).