3

我有一些代码在 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。

谁能帮我弄清楚为什么要转换时间戳?

谢谢

4

3 回答 3

3

正如 Paul Clapham 提到的,postgres 确实总是将时间戳值存储在 UTC 中

对于带时区的时间戳,内部存储的值始终采用 UTC(通用协调时间,传统上称为格林威治标准时间,GMT)。使用该时区的适当偏移量将具有指定明确时区的输入值转换为 UTC。如果输入字符串中没有说明时区,则假定它位于系统的 timezone 参数指示的时区中,并使用时区的偏移量转换为 UTC。

当输出带有时区值的时间戳时,它总是从 UTC 转换为当前时区,并显示为该时区的本地时间。要查看另一个时区的时间,要么更改时区,要么使用 AT TIME ZONE 构造(参见第 9.9.3 节)。

手册的这一部分是指,timestamp with timezone但可以假设相同的内部存储适用于without timezone

于 2010-02-08T20:08:09.653 回答
1

我的问题与 Postgres 的 JAR 文件有关。

在我的旧服务器上,我使用的是 Postgres 7 JAR 文件,一切运行良好。出于某种原因,它在我的新服务器上不再工作了。我用 Postgres 8 替换了 JAR 文件,现在一切正常。当我在数据库中插入时间戳时,它现在插入我的本地时间,而不是 GMT 时间。

感谢大家的帮助。

于 2010-02-09T14:17:39.293 回答
1

当您说“检查我表中的数据”时,我想您正在使用一些数据库查看工具?了解您如何获得这些值会有所帮助。

发现您的数据库将值在内部存储为 UTC,我不会感到惊讶。然后由软件来提取数据以在选定的时区显示它。事实上,我不希望发现它将数据在内部存储为依赖于数据库服务器上的默认时区的东西,因为然后更改该默认时区(或将数据库移动到具有不同默认值的不同服务器) 将更改所有数据。那将是一件坏事。

于 2010-02-08T19:56:15.443 回答