Emi*_*lio 4 java postgresql timezone timestamp jdbc
对于这个 PostgreSQL 测试表:
CREATE TABLE public.test (
id BIGSERIAL,
"datetime" TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
value INTEGER,
CONSTRAINT test_pkey PRIMARY KEY(id)
)
Run Code Online (Sandbox Code Playgroud)
我正在使用这个 SQL 插入:
INSERT INTO it.test (value) VALUES (1);
Run Code Online (Sandbox Code Playgroud)
当我从 EMS 或 PgAdmin 等远程客户端执行 INSERT 时没有问题。字段 datetime 完全填充了服务器时间戳,但是当我使用 Postgres/JDBC 驱动程序 (postgresql-9.2-1002.jdbc4.jar) 从 Java 程序执行 INSERT 时,字段 datetime 填充了与服务器不同的时间戳。
我读到 JVM 使用本地 PC 时区。有什么办法可以避免这种情况吗?
如果我将数据类型从时间戳更改为时间戳z,java会用服务器时间戳填充该字段,但我想在不更改数据类型的情况下解决它,因为该表被其他程序和报告使用。
这里的问题是 PgJDBCTimeZone在连接时将变量设置为 JVM 时区。它需要这样才能使其时间戳代码正确运行并 (IIRC) 正确遵守 JDBC 规范。(详细信息请参见)createPostgresTimeZone。org/postgresql/core/v3/ConnectionFactoryImpl.java
now()是 的别名current_timestamp,它返回timestamp with time zone.
timestamp with time zone从to进行转换timestamp without time zone与写入相同current_timestamp at time zone [the current server TimeZone],即将时间戳重新解释为位于新时区。
由于TimeZone当您通过其他客户端连接时情况不同,因此您会得到不同的结果。因此,对于将 TimeZone 设置为本地时间的客户端来说,您的 DDL 也会是错误的。
为了保持一致,请创建列timestamp with time zone(通常更可取),或将其重新定义default为:
"datetime" TIMESTAMP WITHOUT TIME ZONE DEFAULT now() AT TIME ZONE 'CEST',
Run Code Online (Sandbox Code Playgroud)
...或者无论服务器时区是什么。如果这样做,请小心!指定时区的方法有三种,您必须确保使用与服务器配置中相同的方法,否则它将有不同的夏令时处理!
不用说,我强烈建议仅使用 UTC:
"datetime" TIMESTAMP WITHOUT TIME ZONE DEFAULT current_timestamp AT TIME ZONE 'UTC',
Run Code Online (Sandbox Code Playgroud)
或者最好是timestamp with time zone:
"datetime" TIMESTAMP WITH TIME ZONE DEFAULT current_timestamp,
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2163 次 |
| 最近记录: |