JDBC конвертирует даты в UTC - PullRequest
       14

JDBC конвертирует даты в UTC

3 голосов
/ 08 февраля 2010

У меня есть код, вставляющий метку времени в таблицу Postgres. Вот определение поля, в которое вставлена ​​метка времени:

datelast timestamp without time zone

Я использую этот код Java для обновления данных в поле:

PreparedStatement sqlStatement = connection.prepareStatement(
        "UPDATE datetest SET datelast = ? WHERE id = ? ");
    sqlStatement.setTimestamp(1, new java.sql.Timestamp((new Date()).getTime()));
    sqlStatement.setInt(2, 1);
    sqlStatement.executeUpdate();

Моя проблема в том, что он вставляет метку времени UTC вместо моей метки местного времени (восточное время). Поэтому, когда я проверяю данные в своей таблице, я вижу «2010-02-08 19: 07: 21.261» вместо «2010-02-08 14: 07: 21.261».

На самом деле, у меня был запущен этот код, который я хотел бы запустить на старом сервере, но после переноса кода я получил эту проблему. Проблема не в Postgres, потому что я все еще использую ту же БД. Я также проверил часовой пояс ОС, и они одинаковы. Я также попытался "System.out.println (" TZ = "+ TimeZone.getDefault ());" и я получаю одинаковый часовой пояс на обоих серверах. Поэтому я пришел к выводу, что драйвер JDBC преобразует дату в UTC, прежде чем вставить ее в таблицу.

Может кто-нибудь помочь мне выяснить, почему метка времени конвертируется?

Спасибо

Ответы [ 3 ]

3 голосов
/ 08 февраля 2010

Как отмечает Пол Клэпхем, postgres действительно всегда хранит значения меток времени в UTC :

Для метки времени с часовым поясом внутренне сохраненное значение всегда находится в UTC (универсальное координированное время, традиционно известное как среднее время по Гринвичу, GMT). Входное значение с указанным явным часовым поясом преобразуется в UTC с использованием соответствующего смещения для этого часового пояса. Если во входной строке не указан часовой пояс, предполагается, что он находится в часовом поясе, указанном системным параметром часового пояса, и преобразуется в UTC с использованием смещения для часового пояса.

Когда выводится временная метка со значением часового пояса, она всегда преобразуется из UTC в текущий часовой пояс и отображается как местное время в этой зоне. Чтобы увидеть время в другом часовом поясе, измените часовой пояс или используйте конструкцию AT TIME ZONE (см. Раздел 9.9.3).

Этот раздел руководства относится к timestamp with timezone, но можно предположить, что то же самое внутреннее хранилище применимо к without timezone

1 голос
/ 09 февраля 2010

моя проблема была связана с файлом JAR для Postgres.

На моем старом сервере я использовал JAR-файл Postgres 7, и все работало хорошо. По какой-то причине он больше не работал на моем новом сервере. Я заменил файл JAR на Postgres 8, и теперь все работает хорошо. Когда я вставляю метку времени в БД, она теперь вставляет мое местное время, а не время по Гринвичу.

Спасибо всем за помощь.

1 голос
/ 08 февраля 2010

Когда вы говорите «проверьте данные в моей таблице», я полагаю, вы используете какой-либо инструмент для просмотра базы данных? Было бы полезно узнать, как вы получаете эти значения.

Меня не удивит, что ваша база данных хранит значения внутри UTC. Затем будет зависеть от программного обеспечения, которое извлекает данные для отображения в выбранном часовом поясе. На самом деле я не ожидал бы обнаружить, что он хранит данные внутренне как нечто зависящее от часового пояса по умолчанию на сервере базы данных, потому что затем меняется часовой пояс по умолчанию (или перемещается база данных на другой сервер с другим по умолчанию ) изменил бы все данные. Это было бы плохо.

...