SELECT * FROM table_a
WHERE time_1 >= to_timestamp('11/01/2014 10:00 PDT', 'MM/DD/YYYY HH24:MI TZ')
time_1是UTC时区,是带时区的时间戳。那么,这会给我提供我想要的东西,还是我需要在函数to_timestamp()中做一个精确的UTC时间?
答案 0 :(得分:2)
Postgresql有两种不同的时间戳数据类型,令人困惑的是应该使用哪一种。这两种类型是:
timestamp
(也称为timestamp without time zone
)很可能这是table_a中的类型timestamp with time zone
这是to_timestamp() 您必须确保将苹果与苹果或配对进行比较,而不是将它们混合,否则可能会产生不良后果。
如果您的table_a.time_1
是timestamp with time zone
,那么您在问题中提供的代码就可以正常使用。
如果您的table_a.time_1
是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';
这个(at time zone 'utc'
)的最后一部分将从指定的时间戳中删除时区(PDT),并将时间戳转换为UTC。
编辑:在此回答中帮助您发表评论......
为了理解如何翻译时区,您需要了解两种时间戳形式之间的区别。很明显为什么你需要在下面理解这一点。如上所述,两种形式的时间戳之间的差异令人困惑。有good manual page但现在只需阅读。
要理解的主要是 版本实际上都不存储时区(尽管名称)。如果您添加了额外的单词" translation" ,则命名会更有意义。想想"没有时区翻译的时间戳" 和"带时区翻译的时间戳" 。
timestamp with time zone
翻译根本不存储时区。它旨在存储时间戳,这些时间戳可能来自世界上任何地方,而不是松散的意义。因此,当输入一个时,你必须提供它来自的时区,或者postgresql将假设它来自the time zone of your current session。 Postgresql自动将其从给定时区转换为服务器的内部时区。您不需要知道什么时区,因为postgresql会在给您提供值之前始终将其从此内部时区转换回来。当您检索值(例如:SELECT my_time FROM foo
)时,postgresql会将时间戳转换为当前会话的时区。或者,您可以指定要翻译的时区(例如:SELECT my_time AT TIME ZONE 'PDT' FROM foo
)。
考虑到这一点,您可以更容易理解,timestamp
没有时区转换将永远不会从您指定的时间更改。 Postgresql会将11:00:00
视为12:00:00
之前发生的事件,即使你的意思是11在美国,12在英格兰。很容易理解为什么这可能不是你想要的。
一个非常常见的编程错误是认为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
不变。