Postgresql和Java之间的UTC偏移一小时差异

时间:2013-11-14 13:55:08

标签: java postgresql datetime

我有一个java程序,它以二进制格式生成Postgresql的COPY命令所期望的二进制格式的时区值。数据被写入二进制文件,然后使用copy命令将其插入到Postgresql中,并将其插入带有时间戳列(无时区)的表中。

格式本质上是数字8作为4字节值,后跟自2000-01-01以来的微秒作为8字节值。

我发现Postgresql和Java对时区偏移的解释有所不同。当我尝试写日期时:

2004-11-01 09:34:42.432

以postgres二进制格式

0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x8a, 0xcd, 0xe3, 0x10, 0x68, 0x00

和postgres正确报告日期。但是,如果我输入日期

2010-11-01 09:34:42.432

以二进制形式显示为

0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x36, 0xf8, 0x72, 0xcb, 0x64, 0x00

我将2010-11-01 08:34:42.432作为Postgres的时间戳。

进一步调查显示,Postgres认为2010年的UTC偏移为-5,而Java认为其-4(我相信这是正确的)导致一小时差异。任何人都知道解决方案是什么?

相关信息:

Postgresql版本9.2.4

Java:7

在东部时区(America / New_York)工作。

操作系统:Linux(正确设置时区)

2 个答案:

答案 0 :(得分:1)

想出来。结果显示Postgres对时间戳列的预期微秒是自2000年1月1日以来的微秒。换句话说,需要从2000年1月1日UTC当前时间减去2000年1月1日当前时间。我正在做后者。

帮助他人的其他信息:

  1. 如果您的列是没有时区的时间戳:从当前时间发送微秒 - 2000年1月1日UTC + tz偏移量(以微秒为单位)
  2. 如果您的列是带时区的时间戳:从当前时间发送微秒 - 2000年1月1日UTC。
  3. (1)有效地成为UTC中的“原样”当前时间(即,如果您在当地时间上午9:00尝试,如果偏移为-3,则不要将它设为12:00 pm,而是编码它截至UTC时间上午9:00 UTC减去2000年1月1日UTC。重要的是,这与当地时区的当前时间不一样 - (2000年1月1日当地时区)。

    Gratuitous plug 我有一个Java库,可以使用来自JPA注释实体集合的COPY命令直接将行插入到Postgresql中。可在github上找到:https://github.com/eclecticlogic/pedal-dialect

答案 1 :(得分:0)

Linux命令行的快速测试表明2010-11-01在America / New_York是EDT(-4)。你在Postgresql和Java中有相同的时区规范吗?您使用的是哪个Java版本 - 它们使用相同的TZif数据库,但可能使用不同的版本。如果使用Postgresql 9.2.4或更高版本进行测试,会得到相同的结果吗?