我遇到了一个问题,我的用户定义函数(UDF)是用JavaScript语言在雪花中实现的,它返回无效日期,它得到了一天。
为了演示问题,这里有一个简单的UDF,它包含三个参数--年份、月、日和返回日期对象。
CREATE OR REPLACE FUNCTION JDC(YEAR FLOAT,MONTH FLOAT,DAY FLOAT)
RETURNS DATE
LANGUAGE JAVASCRIPT
AS
$$
// In Java Script months start with 0 so -1
return new Date(YEAR,MONTH-1,DAY)
$$
;调用此过程将返回所有年份的正确值,1942年至1949年之间的几天除外,
select JDC(1942,02,10);返回1942-02-11,这是不正确的。select JDC(1948,12,31);返回1949-01-01,这是错误的。select JDC(2020,02,10);返回2020-02-10,正确值。如果您注意到1,2在javascript日期转换为雪花的过程中,有一天它会增加。我确认JavaScript能够返回正确的值,方法是将UDF返回类型更改为VARCHAR,并以字符串形式返回日期对象,如return new Date(YEAR,MONTH-1,DAY).toString(),因此在转换过程中发生了一些事情。
默认情况下,JavaScript使用UTC时区,并且我的当前雪花实例设置为在PST时区中运行,因此认为时区一侧的转换应该回到前一天,但令人惊讶的是,它会以相反的方式运行。
发布于 2020-11-15 21:32:49
发布于 2020-11-16 01:43:13
为了避免雪花会话和JavaScript之间奇怪的时区转换,请将自己的时区设置为GMT:
ALTER SESSION SET TIMEZONE = 'America/New_York';
select JDC(1942,02,10);
# `1942-02-11` wrong
ALTER SESSION SET TIMEZONE = 'GMT';
select JDC(1942,02,10);
# `1942-02-10`, as expected.Javascript在日期、时间和时区方面很奇怪--正如您所注意到的,月份是基于0的,而构造函数中的其余日期则不是。另一个问题是Javascript并不只有一个“日期”构造函数,因为Date()代表一个日期时间。
从医生那里:
JavaScript日期对象被转换为UDF的结果数据类型,遵循从TIMESTAMP_LTZ(3)到返回数据类型的转换语义。https://docs.snowflake.com/en/sql-reference/udf-js.html#dates
https://stackoverflow.com/questions/64840142
复制相似问题