【问题标题】:SQL query date according to time zoneSQL根据时区查询日期
【发布时间】:2013-09-05 12:44:56
【问题描述】:

我们使用的 Vertica 数据库的表列类型为 timestamptz,所有数据均根据 UTC 时区插入。 我们使用的是spring-jdbc的NamedParameterJdbcTemplate

所有查询均基于完整的日历日,例如开始日期 2013/08/01 和结束日期 2013/08/31,这会将所有内容都放在 '2013/08/01 00:00:00.0000' 和 '2013/08/31 23:59:59.9999' 之间

我们正在尝试修改我们的查询以考虑时区,即我可以为我的本地时区我可以要求 '2013/08/01 00:00:00.0000 Asia/Jerusalem' 直到 '2013/08/31 23:59 :59.9999 Asia/Jerusalem',与 '2013/08/01 00:00:00.0000 UTC' 到 '2013/08/31 23:59:59.9999 UTC' 明显不同。

到目前为止,我找不到这样做的方法,我尝试在会话中设置时区:

将时区设置为“亚洲/耶路撒冷”;

这甚至在我的数据库客户端中都不起作用。

计算 Java 代码中的差异对我们不起作用,因为我们还有返回日期分组的查询(这会完全搞砸)。

有什么想法或建议吗?

【问题讨论】:

    标签: sql jdbc timezone spring-jdbc vertica


    【解决方案1】:

    我不熟悉 Veritca,但有一些一般性建议:

    • 通常最好对日期范围查询使用半开间隔。开始日期应包含在内,而结束日期应不包含。换句话说:

      start <= date < end
      

      start <= date && end > date
      

      您的结束日期不是'2013/08/31 23:59:59.9999',而是第二天的开始日期,或'2013/09/01 00:00:00.0000'。这避免了与小数精度有关的问题。

      该示例用于查找单个日期。由于您要查询一系列日期,因此您有两个输入。所以它会是:

      startFieldInDatabase >= yourStartParameter
          AND
      endFieldInDatabase < yourEndParameter
      

      同样,您将首先将结束参数值递增到第二天的开始。

    • 鉴于您在回答中谈到了 timestamptz 类型,听起来 Vertica 可能知道 TZ。假设它们类似于Oracle's TIMESTAMPTZ type,那么听起来您的解决方案可以正常工作。

    • 但通常,如果您在数据库中以 UTC 格式存储时间,那么您只需提前转换查询输入时间。因此,与其在'2013/08/01 00:00:00.0000''2013/09/01 00:00:00.0000' 之间进行查询,不如提前转换它并在'2013/07/31 21:00:00.0000''2013/08/31 21:00:00.0000' 之间进行查询。已经有很多帖子介绍了如何在 Java 中原生或使用 Joda Time 进行这种转换,所以我不会在这里重复。

    • 附带说明,您应该确保您使用的任何 TZDB 实现(Vertica、Java 或 JodaTime)都具有最新的 2013d update,因为其中包括今年生效的 change for Israel's daylight saving time rule .

    【讨论】:

    • 谢谢,我们正在这样做(我们实际上对此有过争论,因为我声称这是正确的方法)
    • 明智的回答。半开通常用于日期时间的工作,这很有意义并且可以为您省去悲伤。 Joda-Timejava.time 框架都使用此逻辑。
    【解决方案2】:

    好吧,很明显:

    将时区设置为“亚洲/耶路撒冷”;

    工作了,我只是没有意识到,但为了帮助其他人,我将添加其他有效的东西:

    从 my_table 中选择时区“亚洲/耶路撒冷”的字段;

    适用于 timestamptz 字段

    【讨论】:

    • 您的数据库默认为当地时间还是格林威治标准时间?这会改变你的方法吗?好像不会。
    • 设置为 UTC。我们的农场为世界各地的客户提供服务
    • 我没有时间测试任何东西,但是当我过去做这类事情时,我搜索了 PostgreSQL 解决方案,因为它们使用相同的基本引擎(或其他)。您可以将时间戳列转换为特定时区。
    猜你喜欢
    • 1970-01-01
    • 2021-05-21
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多