Часть 1:
У меня есть файл, содержащий дату в виде строки в следующем формате: 2006-02-16T21:36:32.000+0000
Мне нужно записать это значение в Postgres в столбце типа Timestamp. Как мне это сделать на Java?
Часть 2:
Мне нужно прочитать значение, сохраненное в части 1 из Postgres, и преобразовать его в строку следующего формата "2006-02-16T21:36:32.000+0000"
Вот что я пробовал:
Timestamp lastSyncDate = Timestamp.valueOf(2006-02-16T21:36:32.000+0000)
Когда я пытаюсь записать его в postgres, появляется следующая ошибка:
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
Также избегайте класса Timestamp, он давно устарел. Вместо этого используйте java.time, современный API даты и времени Java. Из этого API лучше всего использовать Instant, если это возможно, как в Ответ Бэзила Бурка; если не пойдет, то LocalDateTime.




2006-02-16T21:36:32.000+0000 выглядит как временная метка ISO-8601.
postgres понимает этот формат. просто относитесь к ней как к любой другой строке.
не пытайтесь преобразовать его в метку времени Java
Фактически, передача этой строки в столбец типа TIMESTAMP (как указано в вопросе) приводит к потере данных. Смещение от UTC игнорируется и отбрасывается. Подробнее см. мой ответ.
myPreparedStatement.setObject(
… ,
OffsetDateTime.parse( "2006-02-16T21:36:32.000+0000" )
)
Вы сказали, что ваша колонка относится к типу TIMESTAMP, что является сокращением от TIMESTAMP WITHOUT TIME ZONE. В этом типе намеренно отсутствует понятие часового пояса или смещения от UTC. Нет обычно подходит для общих деловых целей.
Это неправильный тип для вашего ввода. Ваш ввод имеет нулевое смещение от UTC, что означает сам UTC. Имея смещение или зону, ваши данные типа следует хранить только в TIMESTAMP WITH TIME ZONE столбец. В этом типе …WITH… в Postgres любая отправленная информация о смещении / зоне используется для корректировки в формате UTC для хранения, а затем отбрасывается.
Сохранение значения даты и времени со смещением или зоной в столбце типа TIMESTAMP WITHOUT TIME ZONE аналогично сохранению цены / стоимости в указанной валюте (доллары США, евро, рубли и т. д.) В столбце числового типа. Вы теряете жизненно важные данные, валюту. Это делает ваши данные бесполезными.
См. Страница документации Postgres для этих типов.
По возможности используйте объекты для обмена данными с вашей базой данных, а не передавайте строки счетчиков. Пусть ваш Драйвер JDBC выполняет свою работу в маршалинг данных вперед и назад.
Разберите входную строку как объект OffsetDateTime.
Ваши входные строки имеют формат, определенный стандартом ISO 8601. Классы java.time по умолчанию используют форматы ISO 8601 при синтаксическом анализе / генерации строк. Нет необходимости указывать шаблон форматирования.
String input = "2006-02-16T21:36:32.000+0000" ;
OffsetDateTime odt = OffsetDateTime.parse( input ) ;
Определите свой SQL как подготовленный оператор.
С JDBC 4.2 и новее вы можете напрямую обмениваться объектами java.time с вашей базой данных. Нет необходимости когда-либо снова использовать унаследованные классы, такие как java.sql.Timestamp.
Вы можете передать OffsetDateTime. Мне нравится извлекать Instant, чтобы продемонстрировать читателю, что я понимаю, как Postgres всегда сохраняет значение TIMESTAMP WITH TIME ZONE в формате UTC.
Instant instant = odt.toInstant() ;
myPreparedStatement.setObject( … , instant ) ;
Извлечение.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Не могли бы вы сделать тип этого столбца в Postgres
timestamp with time zone? Поскольку ваша строка имеет смещение по всемирному координированному времени.+0000означает смещение 0 от UTC. Если нет, вам, по крайней мере, нужно знать или решить часовой пояс или смещение UTC ваших временных меток. Если вы можете решить, я выберу UTC.