tl;dr
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 | раз: 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 кратко и только для обмена с базой данных.
person
Basil Bourque
schedule
27.08.2016