在 'COPY .. TO ..' 期间将给定时区的时间戳转换为本地时间
Transform timestamp to local time for a given timezone during 'COPY .. TO ..'
我在 PostgreSQL 数据库中有一个日志 table,其中一个 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 将时间戳 -> 字符串转换为给定的时区。我怎样才能做到这一点?
首先,在处理多个时区时,您应该使用 timestamptz
而不是 timestamp
。会完全避免这个问题。
详情:
- Ignoring timezones altogether in Rails and PostgreSQL
您可以像@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
类型,则时区部分只是 被忽略 并且您最终得到 different 值。因此,如果您 运行 在会话中使用与原始 timestamp
值相同时区设置的 COPY
语句,建议的操作 会发生 上班。
然而,干净的方法是通过应用 AT TIME ZONE
两次[=74 来生成正确的 timestamp
值=]:
SELECT <b>event AT TIME ZONE 'my_target_tz' AT TIME ZONE 'my_source_tz'</b>, ...
FROM logtable
ORDER BY event desc;
'my_target_tz'
是"your own time zone"和'my_source_tz'
示例中云服务器的时区。为确保遵守 DST,请使用 时区名称 ,而不是时区缩写。 The documentation:
A time zone abbreviation, for example PST
. Such a specification merely
defines a particular offset from UTC, in contrast to full time zone names
which can imply a set of daylight savings transition-date rules as well.
相关:
- Accounting for DST in Postgres, when selecting scheduled items
- Time zone names with identical properties yield different result when applied to timestamp
或者,更好的是,到处使用 timestamptz
,它会自动正常工作。
我在 PostgreSQL 数据库中有一个日志 table,其中一个 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 将时间戳 -> 字符串转换为给定的时区。我怎样才能做到这一点?
首先,在处理多个时区时,您应该使用 timestamptz
而不是 timestamp
。会完全避免这个问题。
详情:
- Ignoring timezones altogether in Rails and PostgreSQL
您可以像@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
类型,则时区部分只是 被忽略 并且您最终得到 different 值。因此,如果您 运行 在会话中使用与原始 timestamp
值相同时区设置的 COPY
语句,建议的操作 会发生 上班。
然而,干净的方法是通过应用 AT TIME ZONE
两次[=74 来生成正确的 timestamp
值=]:
SELECT <b>event AT TIME ZONE 'my_target_tz' AT TIME ZONE 'my_source_tz'</b>, ...
FROM logtable
ORDER BY event desc;
'my_target_tz'
是"your own time zone"和'my_source_tz'
示例中云服务器的时区。为确保遵守 DST,请使用 时区名称 ,而不是时区缩写。 The documentation:
A time zone abbreviation, for example
PST
. Such a specification merely defines a particular offset from UTC, in contrast to full time zone names which can imply a set of daylight savings transition-date rules as well.
相关:
- Accounting for DST in Postgres, when selecting scheduled items
- Time zone names with identical properties yield different result when applied to timestamp
或者,更好的是,到处使用 timestamptz
,它会自动正常工作。