我在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转换时间戳 - >字符串到给定的时区。我怎样才能做到这一点?
答案 0 :(得分:2)
首先,每当处理多个区域时,您应该使用 timestamptz
而不是timestamp
。完全可以避免这个问题。
详细说明:
你可以使用像@NuLo suggests这样的AT TIME ZONE
构造,可能甚至可以正常工作,但不完全如上所述。
AT TIME ZONE
将类型timestamp
(timestamp without time zone
)转换为timestamptz
(timestamp 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
并且它会自动正常工作。