我们使用的是一个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中选择时区"亚洲/耶路撒冷"的封地
将适用于时间戳字段