在PostgreSQL中,我们可以直接比较两个带有不同时区的时间戳吗?

Eri*_* He 5 sql postgresql timezone timestamp

SELECT * FROM table_a 
WHERE time_1 >= to_timestamp('11/01/2014 10:00 PDT', 'MM/DD/YYYY HH24:MI TZ')
Run Code Online (Sandbox Code Playgroud)

time_1是UTC时区,它是带有时区的时间戳。那么,这会给我我想要的东西还是我需要在to_timestamp()函数中执行精确的UTC时间?

Phi*_*ing 5

Postgresql有两种不同的时间戳数据类型,并且在使用哪种时会令人困惑。这两种类型是:

  • timestamp (也称为timestamp without time zone),很可能是table_a中的类型
  • timestamp with time zone这是to_timestamp()返回的数据类型

您必须确保将苹果与苹果或成对配对而不是将它们混合在一起,否则可能会得到不良结果。

如果您table_a.time_1是a,timestamp with time zone那么您在问题中提供的代码将可以正常工作。

如果您table_a.time_1是a,timestamp则需要更改代码:

SELECT * 
  FROM table_a 
 WHERE time_1 >= to_timestamp('11/01/2014 10:00 PDT', 'MM/DD/YYYY HH24:MI TZ') at time zone 'utc';
Run Code Online (Sandbox Code Playgroud)

此(at time zone 'utc')的最后一部分将剥离指定的时间戳记中的时区(PDT),并将时间戳记转换为UTC。


编辑:以帮助您在此答案中的评论...

为了了解如何转换时区,您需要了解两种时间戳形式之间的差异。很清楚为什么您需要在下面理解这一点。正如我上面指出的那样,两种形式的时间戳之间的差异令人困惑。有一个很好的手册页,但现在继续阅读。

要了解的主要内容是,两个版本都没有实际存储时区(尽管有名称)。如果您添加了额外的单词“ translation”,则命名会更有意义。考虑“没有时区转换的时间戳“有时区转换的时间戳”

一个timestamp with time zone 翻译完全不存储时区。它旨在存储可能来自世界任何地方的时间戳,并且对其含义没有宽松的追踪。因此,在输入一个时,您必须提供它来自的时区,否则postgresql将假定它来自您当前会话的时区。PostgreSQL自动将其从给定的时区转换为服务器的内部时区。您不需要知道哪个时区,因为在给您赋值之前,postgresql总是将其从该内部时区转换回去。当您检索值(例如SELECT my_time FROM foo:)时,PostgreSQL将时间戳转换为当前会话的时区。或者,您可以指定要转换成的时区(例如:)SELECT my_time AT TIME ZONE 'PDT' FROM foo

考虑到这一点,您将更容易理解,从指定的时间开始,timestamp 无时区转换将永远不会改变。即使您在美国表示11岁,在英国表示12岁,Postgresql也会11:00:00视为之前发生的事情12:00:00。很容易看出为什么这可能不是您想要的。

一个非常常见的编程错误是认为a timestamp with time zone在特定时区。不是。无论您要求哪个时区。而且,如果您未指定所需的时区,则postgresql将假定您希望在当前会话时区使用。

你说,你的领域是timestamp with time zone它们都在UTC。从技术上讲这是不正确的。您的会话时区很可能是UTC,因此postgresql会为您提供UTC中的所有内容。

因此,您有一个timestamp with time zone,您想知道PDT中的这些时间吗?容易:SELECT my_time AT TIME ZONE 'PDT' FROM foo

了解AT TIME ZONE '...'语法在timestamp和之间切换非常重要timestamp with time zone

  • timestamp AT TIME ZONE 'PDT'转换为,timestamp with time zone并告诉postgresql转换为PDT时区。
  • timestamp with time zone AT TIME ZONE 'PDT'转换为一个有timestamp说服力的postgresql,以将其解释为来自“ PDT”。

这种对称性意味着AT TIME ZONE 'foo'您只需反转即可AT TIME ZONE 'foo'。换种方式SELECT anything AT TIME ZONE 'PDT' AT TIME ZONE 'PDT'将始终anything保持不变。