Я пытаюсь сохранить OffsetDateTime("2019-01-14 21:10:00.02+03")
с часовым поясом (+03), используя JDBC для PostgreSQL. Но при получении данных с помощью sql-запроса я всегда получаю результат +00. Есть ли способ сохранить смещение (+03) с датой и временем в postgres?
Как сохранить OffsetDateTime в метку времени PostgreSQL со столбцом часового пояса
Ответы (2)
Есть ли способ сохранить смещение (+03) с датой и временем в postgres?
Да, но, как говорит @Andreas, смещение должно быть в отдельном столбце. Имя типа столбца timestamp with time zone
в PostgreSQL немного вводит в заблуждение; это действительно просто timestamp converted to utc
. Исходное смещение не сохраняется со значением отметки времени.
Теперь у вас может возникнуть соблазн добавить новый столбец varchar
и сохранить смещение как строку hh:mm
, например,
id twtz twtz_offset
-- ---------------------- -----------
1 2019-01-15 07:00:00+00 -07:00
но на самом деле было бы лучше извлечь смещение в секундах с помощью ZoneOffset#getTotalSeconds()
и сохранить его в столбце integer
, например,
id twtz twtz_offset
-- ---------------------- -----------
1 2019-01-15 07:00:00+00 -25200
потому что это число может быть применено непосредственно к значению UTC для обратного преобразования в исходный OffsetDateTime
без необходимости переводить смещение из String
в int
OffsetDateTime odtRetrieved = rs.getObject("twtz", OffsetDateTime.class); // always UTC for PostgreSQL
// odtRetrieved is 2019-01-15T07:00Z
OffsetDateTime odtOriginal = odtRetrieved
.toInstant()
.atOffset(ZoneOffset.ofTotalSeconds(rs.getInt("twtz_offset")));
// odtOriginal is 2019-01-15T00:00-07:00
и он также предлагает некоторую дополнительную надежность на случай, если вы когда-нибудь столкнетесь со странным смещением, которое на самом деле составляет не целую минуту.
(Если вы думаете, что этого никогда не произойдет, тогда следите за грядущим техникой / ужастиком Джона Скита «Правила часовых поясов почти сломали мне мозг». Основанный на реальных событиях. Скоро в книжных магазинах.)
Postgres хранит все в формате UTC и не сохраняет исходный часовой пояс.
with timezone
просто означает, что значение будет преобразовано для вас в часовой пояс сеанса, что бессмысленно в контексте JDBC, поэтому вы всегда получаете значение в формате UTC.
Если вам нужно сохранить смещение часового пояса, вам нужно сохранить его в отдельном столбце самостоятельно.