根据时区的SQL查询日期



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

所有查询都基于完整的日历日,例如开始日期2013/08/01和结束日期2013/08/21,这使得所有查询都在"2013/08/0100:00:00.0000"one_answers"2013/08/21:23:59:59.9999"之间

我们正在尝试修改我们的查询以考虑时区,即我可以为我的本地时区请求"2013/08/01 00:00:00.00亚洲/耶路撒冷"至"2013/08/11 23:59:59.999亚洲/耶路撒冷",这与"2013/08/21 00:00:00.00 UTC"至"2013/08/31 23:59:57.999 UTC"明显不同。

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

将时区设置为"亚洲/耶路撒冷"

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

计算Java代码中的差异对我们来说是不可行的,因为我们还有返回日期分组的查询(这将完全搞砸)。

有什么想法或建议吗?

我不熟悉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的TIMESTAMPTZ类型,那么听起来您的解决方案会很好地工作。

  • 但通常,如果您在数据库中存储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更新,因为这包括今年生效的以色列夏令时规则的更改。

好的,很明显:

将时区设置为"亚洲/耶路撒冷"

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

从my_table中选择时区"亚洲/耶路撒冷"的封地

将适用于时间戳字段

相关内容

  • 没有找到相关文章

最新更新