Ошибка java.time.format.DateTimeParseException: не удалось проанализировать, найден неразобранный текст по индексу 10

Я пытаюсь поставить следующую строку, используя LocalDateTime, но всегда получаю ошибку de unparsed text found:

Error java.time.format.DateTimeParseException: Text '2016-08-18 14:27:15.103+02' could not be parsed, unparsed text found at index 10

Вот моя строка: convertDate: ' 2016-08-18 14: 27: 15.103 +02 '

И мой код:

public static LocalDate conversorStringToLocalDateTime(String convertDate) throws ParseException {
    LocalDate dateTime =LocalDate.parse(convertDate);
    return dateTime;
}

Я думаю, это не слишком сложно, купить я не могу увидеть ошибку. Может ли причина +02 в строке?

2 ответа

Решение

ТЛ; др

OffsetDateTime odt = OffsetDateTime.parse ( "2016-08-18 14:27:15.103+02" , DateTimeFormatter.ofPattern ( "yyyy-MM-dd HH:mm:ss.SSSX" ) ) ;

подробности

Ответ от greg-449 является правильным в отношении проблемы (с использованием объекта "только дата" для значения даты и времени), но не в ее решении.

Этот ответ использует LocalDateTime который излишне выбрасывает ценную информацию о смещении от UTC. LocalDateTime не представляет конкретный момент на временной шкале, только смутное представление о возможных моментах в зависимости от настройки в конкретном часовом поясе.

+02 смещение от UTC, означающее "два часа впереди UTC ". Таким образом, в UTC время дня для этого одновременного момента составляет 12 часов, что на 2 часа меньше, чем ваши 14 часов. Это представляет определенный момент на временной шкале. Это смещение является ценной информацией, которую вы выбрасываете с LocalDateTime а не OffsetDateTime,

Формат вашей строки в формате SQL, который близок к стандартному формату ISO 8601. Просто замените ПРОСТРАНСТВО в середине T, Классы java.time по умолчанию используют форматы ISO 8601, поэтому нет необходимости указывать шаблон форматирования.

String input = "2016-08-18 14:27:15.103+02";
String inputModified = input.replace ( " " , "T" );

К сожалению, в Java 8 есть ошибка при разборе значений смещения, сокращенного до часа или значений смещения, пропускающих двоеточие между часами и минутами. Исправлено в Java 9. Но в Java 8 нам нужно настроить ввод.

// Workaround for Java 8 where 2-digit offset fails parsing. Fixed in Java 9.
int lengthOfAbbreviatedOffset = 3;
if ( inputModified.indexOf ( "+" ) == ( inputModified.length () - lengthOfAbbreviatedOffset ) ) {
    // If third character from end is a PLUS SIGN, append ':00'.
    inputModified = inputModified + ":00";
}
if ( inputModified.indexOf ( "-" ) == ( inputModified.length () - lengthOfAbbreviatedOffset ) ) {
    // If third character from end is a PLUS SIGN, append ':00'.
    inputModified = inputModified + ":00";
}

Сейчас разбираюсь.

OffsetDateTime odt = OffsetDateTime.parse ( inputModified );

Дамп на консоль. Обратите внимание, как мы изменились +02 в +02:00,

System.out.println ( "input: " + input + " | inputModified: " + inputModified + " | odt: " + odt );

ввод: 2016-08-18 14:27:15.103+02 | InputModified: 2016-08-18T14:27:15.103+02:00 | odt: 2016-08-18T14:27:15.103+02:00

Или укажите шаблон форматирования. Ошибка смещения-разбора не кусается при использовании этого шаблона форматирования.

    DateTimeFormatter f = DateTimeFormatter.ofPattern ( "yyyy-MM-dd HH:mm:ss.SSSX" );
    OffsetDateTime odt = OffsetDateTime.parse ( input , f );

База данных

Исходя из Postgres, вы должны извлекать значение как объект даты-времени, а не как строку.

Если ваш драйвер JDBC соответствует JDBC 4.2, вы можете позвонить ResultSet::getObject чтобы получить Instant или же OffsetDateTime, Если нет, позвоните ResultSet::getTimestamp чтобы получить java.sql.Timestamp, а затем немедленно преобразовать в java.time, позвонив toInstant на объекте Timestamp.

Придерживайтесь java.time для вашей бизнес-логики; используйте типы java.sql кратко и только для обмена с базой данных.

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

Так что вы должны использовать LocalDateTime но LocalDateTime.parse(String) ожидает дату формата ISO, которая не является тем форматом, который вы используете.

Так что вам нужно использовать DateTimeFormatter указать формат вашей входной строки. Что-то вроде:

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSX");
LocalDateTime result = LocalDateTime.parse(convertDate, format);
Другие вопросы по тегам