我有一个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(正确设置时区)
答案 0 :(得分:1)
想出来。结果显示Postgres对时间戳列的预期微秒是自2000年1月1日以来的微秒。换句话说,需要从2000年1月1日UTC当前时间减去2000年1月1日当前时间。我正在做后者。
帮助他人的其他信息:
(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或更高版本进行测试,会得到相同的结果吗?