如何防止 Redshift INSERT 日期时间删除时区?

oky*_*eni 1 sql amazon-redshift

我有String这种格式的 a:2018-11-01T00:00:00-07:00我想将它转换为 aTIMESTAMP并将其插入到一TIMESTAMP列中。但是,当我插入它时,它会删除-07:00而不先将其转换为-00:00. 如何确保它被正确转换并存储在 Redshift 中?

下面是一个例子: select ORIGINAL_DATE, TO_TIMESTAMP(ORIGINAL_DATE,'YYYY-MM-DD HH24:MI:SS') FROM CDW_LANDING.X where id = XXXXXX;

=> 2018-11-01T00:00:00-07:00 2018-10-31 17:00:00

TO_TIMESTAMP其转换为2018-10-31 17:00:00这是我想要的。但是,当我插入它时,它会变成2018-11-01 00:00:00并简单地删除-07:00.

这是示例:

insert into cdw_stage.X (ORIG_DT) 
select TO_TIMESTAMP(ORIGINAL_DATE,'YYYY-MM-DD HH24:MI:SS') 
from CDW_LANDING.INVOICE where id = XXXXXX;
Run Code Online (Sandbox Code Playgroud)

但是当我用 查询它时select ORIG_DT from cdw_landing.X;,它显示2018-11-01 00:00:00. 我想看到的是2018-10-31 17:00:00这是什么样TO_TIMESTAMP的功能应该做的。

ORIG_DT在红移是TIMESTAMP格式。输入日期在VARCHAR.

How do I get Redshift to save this correctly? I also added postgres tag because Redshift is based off of postgres. Thank you so much!!!

Erw*_*ter 5

2018-11-01T00:00:00-07:00 is not a timestamp (timestamp without time zone) literal, strictly speaking. It is a timestamptz (timestamp with time zone) literal. This is the root of all pain in your question. The wrong cast to timestamp ignores the offset. The Postgres manual:

In a literal that has been determined to be timestamp without time zone, PostgreSQL will silently ignore any time zone indication. That is, the resulting value is derived from the date/time fields in the input value, and is not adjusted for time zone.

Bold emphasis mine.

The use of TO_TIMESTAMP() can't save you. The Redshift manual:

Formats that include a time zone (TZ, tz, or OF) are not supported as input.

(The same is true in Postgres.)

Solution

Cast to timestamptz (or use a column of that type to begin with), the rest should fall in place:

SELECT cast('2018-11-01T00:00:00-07:00' AS timestamptz);
Run Code Online (Sandbox Code Playgroud)

Or:

SELECT '2018-11-01T00:00:00-07:00'::timestamptz;
Run Code Online (Sandbox Code Playgroud)

The manual about casting in Redshift.

When an actual timestamptz is assigned to a timestamp column it is converted according to the current timezone setting of the session automatically. If you want a different target timezone, use the AT TIME ZONE construct. Details:

The related answer is for Postgres, but timestamp handling in Redshift (while differing in many other aspects!) is the same. The Redshift manual:

将 DATE 或 TIMESTAMP 转换为 TIMESTAMPTZ 时,假定 DATE 或 TIMESTAMP 使用当前会话时区。会话时区默认为 UTC。有关设置会话时区的更多信息,请参阅timezone