在'COPY .. TO ..'期间将时间戳转换为给定时区的本地时间

时间:2015-09-02 11:50:11

标签: postgresql types timezone timestamp

我在PostgreSQL数据库中有一个日志表,其中event列的类型为timestamp without time zone

现在我有一个bash脚本,它从日志数据库中创建一个CSV文件:

...
psql .. -c "COPY (SELECT event, ... FROM logtable order by event desc) TO STDOUT WITH CSV" logdb > log.csv
...

这是在托管数据库的云服务器上执行的,因此,log.csv中的时间戳字符串是服务器时区的本地时间。

但是,我喜欢使用时间戳字符串来表示我自己时区的时间。所以我将能够让psql转换时间戳 - >字符串到给定的时区。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

首先,每当处理多个区域时,您应该使用 timestamptz 而不是timestamp。完全可以避免这个问题。

详细说明:

可以使用像@NuLo suggests这样的AT TIME ZONE构造,可能甚至可以正常工作,但不完全如上所述。

AT TIME ZONE将类型timestamptimestamp without time zone)转换为timestamptztimestamp with time zone),反之亦然。 timestamptz值的 文本表示 取决于运行命令的会话中时区的当前设置 。这两个timestamptz 100%相同(表示相同的时间点):

'2015-09-02 15:55:00+02'::timestamptz
'2015-09-02 14:55:00+01'::timestamptz

但是文本表示是而不是。显示屏适用于不同的时区。如果您使用此字符串文字并将其提供给timestamp类型,则时区部分只是忽略,您最终会得到不同的值。因此,如果您在会话中使用与原始COPY值相同的时区设置运行timestamp语句,则建议的操作会发生

然而,干净的方法是通过应用timestamp 两次 来生成正确的AT TIME ZONE值:

SELECT event AT TIME ZONE 'my_target_tz' AT TIME ZONE 'my_source_tz', ...
FROM   logtable
ORDER  BY event desc;

'my_target_tz'是“您自己的时区”,'my_source_tz'是示例中云服务器的时区。要确保遵守DST,请使用时区名称,而不是时区缩写。 The documentation:

  

时区缩写,例如PST。这样的说明仅仅是   与全时区域名称相比,定义了与UTC的特定偏移量   这也意味着一套夏令时过渡日期规则。

相关:

或者,更好的是,在任何地方使用timestamptz并且它会自动正常工作。