Должен ли я хранить часовой пояс отдельно от метки времени для Postgres и JDBC?

кажется (и, возможно, я ошибаюсь), что если вы хотите сохранить часовой пояс, когда что-то произошло с JDBC и Postgres, вам нужно сохранить часовой пояс отдельно от метки времени.

то есть я бы предпочел дать моему ORM/JDBC/JPA Java Calendar (или Джода DataTime) С часовой пояс America/New_York к Postgres timestampz поле. И я ожидал бы при извлечении независимо от часового пояса серверов (или по умолчанию в UTC), чтобы вернуть мне Calendar с часовой пояс America/New_York. Но просто глядя на большинство кода JDBC (и вещи, которые зависят от него, что не происходит).

это правильно?

это кажется смешным, что мне нужно будет хранить tz в другом поле, когда postgres поддерживает его.

таким образом, кажется, что только два варианта:

  1. выберите timestampz столбец Postgres как java.util.String и разобрать его.
  2. хранить часовой пояс как отдельное поле.
номер один и два потребуют каких-то перехватчиков преобразования для моих библиотек SQL mapping / ORM.
  • какое лучшее решение для JDBC ?
  • какое лучшее решение для JPA (если отличается от JDBC)?

2 ответов


когда timestamp with time zone (timestamptz) он преобразуется в UTC для хранения в БД. При извлечении он преобразуется в текущий часовой пояс клиента, а не в часовой пояс, в котором он был первоначально. По сути, это момент времени.

есть еще timestamp without time zone (timestamp). Это не подлежит преобразованию, но делает не носите с собой временную метку. Если вы храните timestamp С вашим клиентским часовым поясом, установленным в UTC, а затем получить его, когда клиентский часовой пояс "+08: 00", вы получаете то же значение. Это половина того, что вы хотите, в том, что он сохраняет ценность сырого времени.

имена и поведение ужасны и запутанны, но установлены стандартом SQL.

вы должны хранить часовой пояс отдельно, если вы хотите записать момент времени в определенном часовом поясе. Я бы рекомендовал хранить его как INTERVAL С CHECK ограничение ограничение это colname BETWEEN INTERVAL '-12' HOUR + INTERVAL '1' SECOND AND INTERVAL '12' HOUR. Это определение отвергает -12:00 и принимает +12:00, я не совсем уверен, что это правильно, так проверять.

вы можете либо сохранить timestamp местного времени в этом часовом поясе (что я бы сделал), или хранить timestamptz времени UTC, когда произошло событие плюс смещение, которое позволяет преобразовать его в местное время.

либо будет работать нормально для JDBC. Для JPA это будет зависеть от того, насколько хорошо ваш провайдер понимает и отображает типы интервалов. В идеале вам нужно временное сгенерированное поле в вашей сущности, которое восстанавливает экземпляр календаря, который вы хотите использовать timestamp и interval хранящиеся в базе данных.


EclipseLink поддерживает хранение часового пояса в Oracle, я думаю, вы могли бы получить его для хранения в Postgres, а если вы настроили PostgreSQLPlatform.