将时间与时区进行比较将返回意外结果

rdrgkggo  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(334)

为什么会返回此查询 false ? 是因为 22:51:13.202248 +01:00 格式?

SELECT now()::time at TIME ZONE 'Europe/London'; -- 22:51:13.202248 +01:00

SELECT now()::time at time zone 'Europe/London' > '22:00:00'::time
   AND now()::time < '23:35:00'::time as is_currently_open; -- false
bejyjqdl

bejyjqdl1#

now()::time at time zone 'Europe/London'

... 返回值 time with time zone ( timetz ):
然后你把它和 time [without time zone] . 别这样。这个 time 值被强制为 timetz 在该过程中,根据当前时间偏移量附加时间偏移量 timezone 设置。也就是说,你的表达式在不同的设置下会有不同的计算结果。更重要的是,dst规则没有得到正确的应用。你不要这些!请参见:
db<>在这里摆弄
一般来说,不要使用 time with time zone ( timetz )完全没有。这种类型被设计打破了,官方不鼓励在博士后使用。请参见:
时区相等的postgres时间
改用:

SELECT (now() AT TIME ZONE 'Europe/London')::time > '22:00:00'
   AND (now() AT TIME ZONE 'Europe/London')::time < '23:35:00' AS is_currently_open;

右操作数现在可以是非类型化的文本,它将被强制为 time 应该的。 BETWEEN 对于时间和时间戳,通常是错误的工具。请参见:
如何在时间戳列中添加日/夜指示器?
但看起来 >= 以及 <= 开放时间更合适吗?那么 BETWEEN 符合用例并使其更简单:

SELECT (now() AT TIME ZONE 'Europe/London')::time
       BETWEEN '22:00:00' AND '23:35:00' AS is_currently_open;

相关:
在postgresql中执行此工时查询

u2nhd7ah

u2nhd7ah2#

我认为你只需要调整第二个 predicate 的时区就可以得到你想要的结果:

SELECT 
        now()::time at time zone 'Europe/London' > '22:00:00'::time 
    AND now()::time at time zone 'Europe/London' < '23:35:00'::time 
    ----------------^----------------> here
AS is_currently_open;

相关问题