JDBC将日期转换为UTC

时间:2010-02-08 19:45:32

标签: java postgresql jdbc timestamp utc

我有一些代码在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 个答案:

答案 0 :(得分:3)

正如Paul Clapham所提到的,postgres does indeed always store timestamp values in UTC

  

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

     

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

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

感谢大家的帮助。