在PostgreSQL中明确将时区分配给没有时区的时间戳

时间:2017-07-15 06:40:02

标签: postgresql timezone

用这个把头撞在墙上。如何告诉Postgres不知道时间戳列的时区?我知道基于数据库中另一列的时区 - 时间戳值本身并不知道。

select 
  '2017-07-10 01:30:00'::timestamp as without_tz, 
  '2017-07-10 01:30:00'::timestamp at time zone 'America/New_York' as with_tz
-------------------------
without_tz: 2017-07-10 01:30:00
with_tz:    2017-07-09 22:30:00-07

我想要的输出是:

with_tz:     2017-07-10 01:30:00-07

1 个答案:

答案 0 :(得分:0)

简短回答:

SELECT '2017-07-10 01:30:00'::timestamp AT TIME ZONE 'America/New_York' AT TIME ZONE 'America/New_York';
>> 2017-07-10 01:30:00

首先,输出表明您的时区设置为America / Los_Angeles或其他时区定义,导致时间为UTC-7。您可以使用SHOW TIME ZONE;进行确认。

第二,AT TIME ZONE在时间戳或时间戳上的功能有所不同。请参见the docs,但是将时间戳处理作为指定的时区,并将返回作为具有时区的本地时间:

将时间戳记为纽约,以本地时间戳记返回:

SELECT '2017-07-10 01:30:00'::timestamp AT TIME ZONE 'America/New_York';
>> 2017-07-09 22:30:00-07

将时间戳作为本地时间进行了处理,然后将其转换为指定的时区,并作为没有时区的时间戳返回。

将本地时间戳转换为纽约时间戳

SELECT '2017-07-10 01:30:00'::timestamptz AT TIME ZONE 'America/New_York';
>> 2017-07-10 04:30:00

一旦了解了时间戳到时间戳的转换,就可以可靠地链接AT TIME ZONE命令。

将本地时间戳转换为纽约时间戳,将其视为芝加哥时间并作为本地时间戳返回:

SELECT '2017-07-10 01:30:00'::timestamptz AT TIME ZONE 'America/New_York' AT TIME ZONE 'America/Chicago';
>>  2017-07-10 02:30:00-07

为更明确地解释这一点,该查询将本地时间戳1:30a转换为纽约时间戳4:30a,然后将4:30a视为芝加哥时间戳,并返回本地时间戳2:30a。

类似地,上面的简短回答将1:30a视为纽约时间戳,然后将其转换为纽约时间戳1:30a。