我有一个 Timestamp_NTZ 列,我知道数据位于中部(美国/芝加哥)时区。如何在选择时将其转换为 Timestamp_TZ 格式。
我不能只转换为 varchar 并添加时区偏移量并返回到 timestamp_tz,因为夏令时期间的偏移量不同。
我发现以下两种方法,但它们涉及更多代码/打字。寻找优雅的解决方案。
将会话更改为所需的时区并使用 TO_TIMESTAMP_TZ() 函数。这种方法的缺点是它是两个单独的查询,并且不能在以所有者身份运行的存储过程中使用。
alter session set timezone = 'America/Chicago';
select TO_TIMESTAMP_TZ(column_name) from table_name;
使用TIMESTAMP_TZ_FROM_PARTS函数。这需要更多的打字并且看起来很复杂。
select TIMESTAMP_TZ_FROM_PARTS(Year(column_name), Month(column_name), Day(column_name), Hour(column_name), Minute(column_name), Second(column_name), 0, 'America/Chicago') from table_name;
有没有一种简单的方法可以在雪花中做到这一点,例如:
select TO_TIMESTAMP_TZ(column_name, 'America/Chicago') from table_name;
您应该能够使用 CONVERT_TIMEZONE 来实现此目的。 2 个参数版本并不期望
TIMESTAMP_TZ
正如您在评论中提到的那样。您可以在下面看到,我传入 TIMESTAMP_NTZ
是出于演示目的,但如果您愿意,您也可以传入 2020-01-27T08:00:00Z
之类的字符串:
select CONVERT_TIMEZONE( 'America/Chicago' , TO_TIMESTAMP_NTZ('2020-01-27T08:00:00Z'));
以上回报
2021-01-26 02:00:00.000000000 -06:00
这是一个基本的解决方法,对于输入日期(来自列)为 NTZ 并且您有时区但没有偏移量的情况,不需要扰乱会话。
Convert_timezone 首先将 ntz 值转换为实例本地时区的 tz,然后将其转换为您所需的时区。从转换后的值中去除偏移量,并找到它与原始 ntz 时间之间的差异。然后从转换后的值中减去该差值。
'2022-04-28 16:44:35'
'America/New_York'
'2022-04-28T16:44:35-04:00'
SELECT DATEADD(HOUR, -1 * DATEDIFF(HOUR,'2022-04-28 16:44:35'::TIMESTAMP_NTZ,CONVERT_TIMEZONE('America/New_York','2022-04-28 16:44:35')::TIMESTAMP_NTZ),CONVERT_TIMEZONE('America/New_York','2022-04-28 16:44:35'))
不确定是否有人找到了更好的解决方案,或者雪花是否放入了一些东西,但我还没有找到。
我也遇到了完全相同的问题。你的#2对我有用。我检查了最新的 Snowflake 文档,但没有看到任何可以修复它的内容。当您使用第 1 个参数 CONVERT_TIMEZONE 时,它总是在添加时区名称/偏移之前将时间移动到本地时间。这真的很烦人,Snowflake应该添加一种方法来CONVERT_TIMEZONE而不影响时间值,否则你必须使用复杂的TIMESTAMP_TZ_FROM_PARTS