【问题标题】:One hour discrepancy in UTC offset between Postgresql and JavaPostgresql 和 Java 之间 UTC 偏移量的一小时差异
【发布时间】:2013-11-27 13:47:52
【问题描述】:

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

格式本质上是数字 8 作为 4 字节值,后跟自 2000 年 1 月 1 日以来的微秒作为 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

在东部时区(美国/纽约)工作。

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

【问题讨论】:

    标签: java postgresql datetime


    【解决方案1】:

    想通了。原来 Postgres 期望的时间戳列的微秒是自 2000 年 1 月 1 日 UTC 以来的微秒。换句话说,需要从 2000 年 1 月 1 日 UTC 减去当前时间,而不是从本地 2000 年 1 月 1 日减去当前时间。我在做后者。

    帮助他人的其他信息:

    1. 如果您的列是没有时区的时间戳:从当前时间发送微秒 - UTC 2000 年 1 月 1 日 + tz 偏移量(以微秒为单位)
    2. 如果您的列是带时区的时间戳:从当前时间发送微秒 - 2000 年 1 月 1 日 UTC。

    (1) 在 UTC 中有效地“按原样”变为当前时间(即,如果您尝试当地时间上午 9:00,如果偏移量为 -3,则不要将其设为 UTC 下午 12:00,而是对其进行编码UTC 时间上午 9:00)减去 2000 年 1 月 1 日 UTC。重要的事实是,这与(本地时区的当前时间)-(本地时区的 2000 年 1 月 1 日)不同。

    免费插件 我有一个 Java 库,用于使用 JPA 注释实体集合中的 COPY 命令将行直接插入 Postgresql。可在 github 获取:https://github.com/eclecticlogic/pedal-dialect

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我更新了问题以反映正确的 Postgres 版本:9.2.4
      • 如何在 Postgres 中查看时区规范?有具体的命令吗?
      • 9.2.4 具有 tzinfo 版本 2013b(取自发行说明)。我在 Debian 上安装了 2013c,但 2013b 和 2013c 之间的差异似乎并未涵盖这一点。
      • 至少在 Debian 上,我认为 postgresql 使用的是系统的时区数据,而不是自己的冗余打包。
      • 我认为问题出在 Java 方面。我的测试工具是 2013-11-14 的报告偏移量为 -04,这显然是错误的。进一步调查...编辑..用户错误。 java端的时区是正确的(-05)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 2016-09-05
      • 2011-03-22
      • 2014-12-14
      • 1970-01-01
      相关资源
      最近更新 更多